allocating memory via malloc/calloc
Author |
Message |
news.save-net.co #1 / 10
|
 allocating memory via malloc/calloc
Thanks in advance, I've written several functions which each has a single argument (character strings) and returns the same (char string). I need the function to return a character string. Each functions implementation dynamically allocates memory to build a string for the work that the function does. The problem? Two lines prior to the function's return, I strcpy the functions malloc'd character string (variable) to the global. The line prior to the functions return, I "free" the malloc'd (local) variable which really upsets the compiler (Visual C++ 6.0). One thing........"alloca" worked great (but another compiler I have to port to doesn't support "alloca", hence malloc or calloc. Here's a synopsis of the problem: #include<stdlib.h> #include<stdio.h> char * gvar; char * start(char str[]) { char *lvar; if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL) { /* process */ if ( strlen(gvar) < lvar) { if ( (gvar = realloc( strlen(lvar) + 1, sizeof(char) ) != NULL) strcpy(gvar, lvar); } free(lvar); /* ERROR */ } return gvar; Quote: }
void main(void) { if ( (gvar = (char *)malloc( 256) ) != NULL) { printf("%s\n", start("test")); // would like function to return character string as I next functions } Quote: }
As I said earlier, "alloca" worked fine (didn't have to "free" memory). Any help would be greatly appreciated.
|
Wed, 09 Feb 2005 06:30:05 GMT |
|
 |
Tobias Oe #2 / 10
|
 allocating memory via malloc/calloc
Quote:
> Thanks in advance, > I've written several functions which each has a single argument (character > strings) and returns the same (char string). I need the function to > return > a character string. Each functions implementation dynamically allocates > memory to build a string for the work that the function does. > The problem? Two lines prior to the function's return, I strcpy the > functions malloc'd character string (variable) to the global. The line > prior to the functions return, I "free" the malloc'd (local) variable > which > really upsets the compiler (visual c++ 6.0). One thing........"alloca" > worked great (but another compiler I have to port to doesn't support > "alloca", hence malloc or calloc. > Here's a synopsis of the problem: > #include<stdlib.h> > #include<stdio.h>
#include <string.h> Quote: > char * gvar; > char * start(char str[]) > { > char *lvar; > if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL)
the cast of malloc is not necessairy and potentially dangerous. Quote: > { > /* process */ > if ( strlen(gvar) < lvar)
You compare the length of the string gvar points at to lvar ??? Quote: > { > if ( (gvar = realloc( strlen(lvar) + 1, sizeof(char) ) != NULL)
The first argument to realloc is a void * not a size_t. Read up on it in your favourite C book or the FAQ of this newsgroup. Quote: > strcpy(gvar, lvar);
lvar points to unitialised memory. This is not going to work Quote: > } > free(lvar); /* ERROR */ > } > return gvar; > } > void main(void)
int main(void) Quote: > { > if ( (gvar = (char *)malloc( 256) ) != NULL) > { > printf("%s\n", start("test")); // would like function to return > character string as I next functions > } > } > As I said earlier, "alloca" worked fine (didn't have to "free" memory). > Any help would be greatly appreciated.
This code needs more work. What are you trying to do exactly? Tobias -- unix http://www.faqs.org/faqs/by-newsgroup/comp/comp.unix.programmer.html clc http://www.eskimo.com/~scs/C-faq/top.html fclc (french): http://www.isty-info.uvsq.fr/~rumeau/fclc/
|
Wed, 09 Feb 2005 04:19:35 GMT |
|
 |
Default Use #3 / 10
|
 allocating memory via malloc/calloc
Quote:
> Thanks in advance, > I've written several functions which each has a single argument (character > strings) and returns the same (char string). I need the function to return > a character string. Each functions implementation dynamically allocates > memory to build a string for the work that the function does. > The problem? Two lines prior to the function's return, I strcpy the > functions malloc'd character string (variable) to the global. The line > prior to the functions return, I "free" the malloc'd (local) variable which > really upsets the compiler (visual c++ 6.0). One thing........"alloca" > worked great (but another compiler I have to port to doesn't support > "alloca", hence malloc or calloc.
You have a LOT more problems that that! Quote: > Here's a synopsis of the problem: > #include<stdlib.h> > #include<stdio.h> > char * gvar; > char * start(char str[]) > { > char *lvar; > if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL) > { > /* process */ > if ( strlen(gvar) < lvar)
How is it you think you can compare a string length with a pointer to char? What do you think it will tell you? What is it you really wanted to do here? I can't figure it out. Quote: > { > if ( (gvar = realloc( strlen(lvar) + 1, sizeof(char) ) != NULL)
You just took the string length of lvar, which doesn't at this time hold anything. Very bad. You then passed that length as the first arg to realloc(), which is looking for a pointer. What was it you were trying to do here? Why isn't your compiler complaining like hell? The second arg, which is supposed to be amount of memory you want, is sizeof (char), which is always one. That will give you one byte only. Also, you leaked whatever memory that gvar originally pointed to. If your intent was to expand the buffer for gvar, then you needed to pass it in as the first argument to realloc(). Quote: > strcpy(gvar, lvar);
You just copied the uninitialized contents of lvar to gvar. Kaboom. Quote: > } > free(lvar); /* ERROR */
If the code you presented above is accurate, the heap is probably trashed beyond help. That is normally what happens when free crashes. Quote: > } > return gvar;
Why return a global variable? Why HAVE a global? Quote: > } > void main(void)
main() must return an int. Quote: > { > if ( (gvar = (char *)malloc( 256) ) != NULL) > { > printf("%s\n", start("test")); // would like function to return > character string as I next functions > } > }
You don't seem to understand the realloc() function at all. Please review the documentation. On it. Brian Rodenborn
|
Wed, 09 Feb 2005 04:51:08 GMT |
|
 |
news.save-net.co #4 / 10
|
 allocating memory via malloc/calloc
Sorry..... I keyed in the code from memory (not readily before me) and made a few mistakes that you caught (see very bottom of email for full listing). : > if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL) : : the cast of malloc is not necessairy and potentially dangerous. : Saw this casting format in one of the C books I have....I'll remove it. : > { : > /* process */ : > if ( strlen(gvar) < lvar) : : You compare the length of the string gvar points at to lvar ??? : Typo......should have been ====> if (strlen(gvar) < strlen(lvar)) : > { : > if ( (gvar = realloc( strlen(lvar) + 1, sizeof(char) ) != NULL) : : The first argument to realloc is a void * not a size_t. Read up on it in : your favourite C book or the FAQ of this newsgroup. : Another typo (must have had calloc on the brain). Should have been =====> if ( (gvar = realloc( gvar, strlen(lvar) + 1 ) != NULL) : > strcpy(gvar, lvar); : : lvar points to unitialised memory. This is not going to work : : > } : > free(lvar); /* ERROR */ : > } : > return gvar; : > } : > void main(void) : : int main(void) : : > { : > if ( (gvar = (char *)malloc( 256) ) != NULL) : > { : > printf("%s\n", start("test")); // would like function to return : > character string as I next functions : > } : > } : > : > As I said earlier, "alloca" worked fine (didn't have to "free" memory). : > Any help would be greatly appreciated. : Here's the code minus typos (I hope) :-) #include<stdlib.h> #include<stdio.h> char * gvar; char * start(char str[]) { char *lvar; if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL) { /* process */ if ( strlen(gvar) < strlen(lvar)) { if ( (gvar = realloc( gvar, sizeof(char) ) != NULL) strcpy(gvar, lvar); } free(lvar); /* ERROR */ } return gvar; Quote: }
void main(void) { if ( (gvar = (char *)malloc( 256) ) != NULL) { printf("%s\n", start("test")); // would like function to return character string as I next functions } Quote: }
Thanks again...
|
Wed, 09 Feb 2005 08:19:33 GMT |
|
 |
Eric Sosma #5 / 10
|
 allocating memory via malloc/calloc
Quote:
> Thanks in advance, > I've written several functions which each has a single argument (character > strings) and returns the same (char string). I need the function to return > a character string. Each functions implementation dynamically allocates > memory to build a string for the work that the function does. > The problem? Two lines prior to the function's return, I strcpy the > functions malloc'd character string (variable) to the global. The line > prior to the functions return, I "free" the malloc'd (local) variable which > really upsets the compiler (visual c++ 6.0). One thing........"alloca" > worked great (but another compiler I have to port to doesn't support > "alloca", hence malloc or calloc. > Here's a synopsis of the problem:
You're going to receive quite a few comments about things that have nothing to do with your actual problem, but that's your own fault. Why? Because you didn't post the actual code that's failing, but a "synopsis" that won't even compile. I've read somewhere that in earlier times when Royalty was considered sacrosanct and semi-divine, it would have been an egregious breach of The Right Order Of Things for a lowly commoner to lay hands on the Royal personage. So when a King fell ill, it was out of the question to allow a doctor to examine the ailing monarch. Instead, they'd use a stand-in of lowlier lineage; this person would simulate the King's illness to the best of his ability, and the doctor would examine him instead. Court protocol was thereby satisfied, but I have a suspicion the diagnoses may have been suboptimal. Quote: > #include<stdlib.h> > #include<stdio.h> > char * gvar; > char * start(char str[]) > { > char *lvar; > if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL)
The strlen() function hasn't been declared. C90 compilers may or may not complain about this (C99 compilers must do so), but even if the compiler doesn't complain your program may malfunction here. The problem is that in the absence of a declaration, the compiler will assume strlen() returns an `int', but it actually returns a `size_t'. Functions returning `size_t' may use different conventions than those returning `int', so the register (or whatever) where strlen() deposited its `size_t' return value may not be the same place where the caller retrieves the supposed `int' return value. The cure? #include <string.h>. Quote: > { > /* process */ > if ( strlen(gvar) < lvar)
This can't be right: you're comparing the integral value returned by strlen() to the pointer variable `lvar'. Integers and pointers aren't comparable, and the compiler would have given you a diagnostic here if you'd actually tried this code. Quote: > { > if ( (gvar = realloc( strlen(lvar) + 1, sizeof(char) ) != NULL)
This can't be right: the first argument to realloc() must be a pointer, and you're passing an integral value. Since the #include <stdlib.h> line informed the compiler about realloc(), the compiler would have issued a diagnostic -- again, if this had been the actual code instead of a "synopsis." Quote: > strcpy(gvar, lvar);
`lvar' points to some allocated memory, but nothing has actually been stored in that memory. In particulary, there is no guarantee the memory contains anything C would consider a "string:" a sequence of characters (possibly empty) followed by a byte with value zero. Passing this uninitialized garbage non-string as the second argument of strcpy() is a good way to get demons to fly out of your nose. Quote: > } > free(lvar); /* ERROR */
I see no reason the compiler should complain about this (of course, the compiler is always at liberty to complain about whatever it feels like). But, as we've already established, this isn't the line the compiler complained about, because this code never went through the compiler. Quote: > } > return gvar; > } > void main(void)
main() returns an int. Period. Quote: > { > if ( (gvar = (char *)malloc( 256) ) != NULL) > { > printf("%s\n", start("test")); // would like function to return > character string as I next functions > }
main() returns an int. Period. Quote: > } > As I said earlier, "alloca" worked fine (didn't have to "free" memory). > Any help would be greatly appreciated.
As I said earlier, you'll get more accurately-focused help if you exhibit your actual problem instead of some half-baked approximation. "Synopsis" -- bah! --
|
Wed, 09 Feb 2005 05:05:38 GMT |
|
 |
Default Use #6 / 10
|
 allocating memory via malloc/calloc
Quote:
> Sorry..... > I keyed in the code from memory (not readily before me) and made a few > mistakes that you caught (see very bottom of email for full listing).
Thanks for wasting everyone's time. Quote: > #include<stdlib.h> > #include<stdio.h> > char * gvar; > char * start(char str[]) > { > char *lvar; > if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL) > { > /* process */ > if ( strlen(gvar) < strlen(lvar))
What do you think the length of lvar will be, when you haven't set it to anything? If you tell me it's another typo, I'm going to killfile your sorry ass. Quote: > { > if ( (gvar = realloc( gvar, sizeof(char) ) != NULL) > strcpy(gvar, lvar);
Here you copy the uninitialized buffer to gvar. That does, well who knows what. See my note above. Quote: > } > free(lvar); /* ERROR */
Again, crashes on free() usually means you donked up the heap doing something bad with pointers or overrunning buffers. I still think you should get rid of that global var. If you want to expand the buffer, pass in the existing pointer and either return it's value or the newly allocated expansion. Or pass in a char** and change the pointer's value. Brian Rodenborn
|
Wed, 09 Feb 2005 06:11:32 GMT |
|
 |
#7 / 10
|
 allocating memory via malloc/calloc
|
Wed, 18 Jun 1902 08:00:00 GMT |
|
 |
news.save-net.co #8 / 10
|
 allocating memory via malloc/calloc
Everyone, Thanks for the prior posts.......unfortunately I couldn't post the original code due to constraints beyond my control and had to key in sample thru memory of which I made typos for which I apologize. Here's the code with corrections: #include<stdlib.h> #include<stdio.h> char * gvar; char * start(char str[]) { char *lvar; if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL) { /* process */ if ( strlen(gvar) < strlen(lvar)) { if ( (gvar = realloc( gvar, sizeof(char) ) != NULL) strcpy(gvar, lvar); } free(lvar); /* ERROR */ } return gvar; Quote: }
void main(void) { if ( (gvar = (char *)malloc( 256) ) != NULL) { printf("%s\n", start("test")); // would like function to return character string as I next functions } Quote: }
Now, I can eliminate declaration of gvar as global if the malloc' within function implementation retains the memory (and data in its memory, the heap). I declared the global variable initially because when I'd declare within the function as an array of characters, then return that array variable (last executable line within function), compiler error indicated it was a local variable and removed from the stack.
|
Wed, 09 Feb 2005 09:41:35 GMT |
|
 |
Mark McIntyr #9 / 10
|
 allocating memory via malloc/calloc
On Fri, 23 Aug 2002 18:41:35 -0700, in comp.lang.c , Quote:
>#include<stdlib.h> >#include<stdio.h> >char * gvar;
don't use global variables unless you have to. I see from the below that you're trying not to though ! Quote: >char * start(char str[]) >{ > char *lvar; > if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL)
The cast is unnecessary and potentially dangerous in C. See many many other posts in this group. Quote: > { > /* process */ > if ( strlen(gvar) < strlen(lvar))
At this point, gvar contains random garbage, since you never copied any data into it. Performing strlen on it is lethally dangerous. Quote: > { > if ( (gvar = realloc( gvar, sizeof(char) ) != NULL)
NEVER use realloc like this. If the realloc fails, you just leaked memory. To use it safely, you must use a temporary intermediate variable as several other posters have stated I believe. Also, you just realloced the memory down to one byte. Is that what you intended? I suspect not. Quote: > strcpy(gvar, lvar);
This just trashed your stack because gvar points to memory one byte long, and you copied 5 bytes into it. Quote: > } > free(lvar); /* ERROR */
yes, this is likely. you tried to use strlen on garbage, then tried to copy 5 bytes into a space made for one. So you've corrupted your computer memory. Quote: > } > return gvar;
don't return global variables, its pointless. Quote: >} >void main(void)
as you've been told, C requires main to return an int. Quote: >{ > if ( (gvar = (char *)malloc( 256) ) != NULL)
don't cast malloc. Also, this does not initialise the contents of gvar, so it contains garbage. You can't use strlen on a pointer to garbage. Quote: > { > printf("%s\n", start("test")); // would like function to return >character string as I next functions > } >} >Now, I can eliminate declaration of gvar as global if the malloc' within >function implementation retains the memory (and data in its memory, the >heap).
memory malloc'ed is retained until _you_ free it. Quote: > I declared the global variable initially because when I'd declare >within the function as an array of characters, then return that array >variable (last executable line within function), compiler error indicated it >was a local variable and removed from the stack.
either your implementation is broken, or you returned something peculiar. You should be returning the local variable, not its address. -- Mark McIntyre CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html> CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>
|
Wed, 09 Feb 2005 08:22:17 GMT |
|
 |
Richard Heathfiel #10 / 10
|
 allocating memory via malloc/calloc
Quote:
> Everyone, > Thanks for the prior posts.......unfortunately I couldn't post the original > code due to constraints beyond my control and had to key in sample thru > memory of which I made typos for which I apologize. Here's the code with > corrections: > #include<stdlib.h> > #include<stdio.h> > char * gvar; > char * start(char str[]) > { > char *lvar; > if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL)
The malloc cast is unnecessary, and you'd be better off without it. Quote: > { > /* process */ > if ( strlen(gvar) < strlen(lvar))
gvar points at 256 bytes of memory of an indeterminate nature. Thus, the call to strlen here invokes undefined behaviour. Quote: > { > if ( (gvar = realloc( gvar, sizeof(char) ) != NULL)
You should use a temporary pointer to catch the value of realloc, in case it fails. Note that sizeof(char) is 1, so what you just did was throw away 255 of your 256 bytes of memory. Quote: > strcpy(gvar, lvar);
lvar doesn't have any determinate contents, so you have undefined behaviour again. Quote: > } > free(lvar); /* ERROR */ > } > return gvar; > } > void main(void)
int main(void) Quote: > { > if ( (gvar = (char *)malloc( 256) ) != NULL)
Remove the cast. Quote: > { > printf("%s\n", start("test")); // would like function to return > character string as I next functions > } > } > Now, I can eliminate declaration of gvar as global if the malloc' within > function implementation retains the memory (and data in its memory, the > heap).
So long as you have a pointer to it, you have access to your malloc'd memory. If your pointer goes out of scope, you can't get its value back. Quote: > I declared the global variable initially because when I'd declare > within the function as an array of characters, then return that array > variable (last executable line within function), compiler error indicated it > was a local variable and removed from the stack.
It was correct to indicate that problem. The following program does what I *think* you intend: #include <stdio.h> #include <stdlib.h> #include <string.h> char *start(const char *str, char *p, size_t psize) { char *newp = p; size_t len = strlen(str); if(len >= psize) { newp = realloc(p, len + 1); } if(newp != NULL) { strcpy(newp, str); } else { newp = p; } return newp; Quote: }
int main(void) { char *p = malloc(256); if(p != NULL) { p = start("test", p, 256); printf("%s\n", p); free(p); } return 0; Quote: }
--
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999. C FAQ: http://www.eskimo.com/~scs/C-faq/top.html K&R answers, C books, etc: http://users.powernet.co.uk/eton
|
Wed, 09 Feb 2005 08:39:58 GMT |
|
|
|