Date: Tue, 14 May 2002 02:55:52 +0300 From: Giorgos Keramidas <keramida@ceid.upatras.gr> To: Paul Everlund <tdv94ped@cs.umu.se> Cc: freebsd-questions@FreeBSD.ORG Subject: Re: C malloc question Message-ID: <20020513235552.GB14825@hades.hell.gr> In-Reply-To: <Pine.GSO.4.33.0205131845160.22929-100000@gren.cs.umu.se> References: <Pine.GSO.4.33.0205131845160.22929-100000@gren.cs.umu.se>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2002-05-13 19:06, Paul Everlund wrote: > Hi all! > > I have a question regarding malloc and returning arrays in C. > > The following C program is an example. OK, let's see what could be wrong with this. 1 #include <stdlib.h> 2 #include <string.h> You're missing <stdio.h> which is needed for the prototype of printf() that is used further below (in line 24). 3 4 static char * 5 init(void) 6 { 7 char *str; 8 int i; 9 10 str = (char *)malloc(sizeof(char), 128); You probably meant to write malloc(sizeof(char) * 128) here. Note the multiplication that is used. The malloc() library function doesn't take two arguments. 11 for (i = 0; i < 127; i++) 12 str[i] = "A"; 13 str[i] = '\0'; These three lines can probably be replaced with: bzero((void *) str, 128); or even better, why don't you use calloc() to allocate memory, instead of malloc()? This will zero out the allocated memory for you, before returning the pointer to its start. 14 return str; 15 } 16 17 int 18 main(void) 19 { 20 int i; 21 22 for (i = 0; i < 500000; i++) 23 init(); You are calling init() 500,000 times, and throwing away the pointer that init() returns. This will result in malloc() being called an equal number of times, but you can not free() the allocated memory since you didn't save the pointer it will return. This is bound to exchaust your memory very quickly. 24 printf("%s\n", init()); 25 return 0; 26 } > This program takes up a lot of malloc'ed memory after a while, > so how do one return arrays and free memory in the main function > everytime the array have been used? By saving init()'s return value in a (char *) and calling free() on it, when you're done. For instance... int main(void) { int k; char *ptr; for (k = 0; k < 500000; k++) { ptr = init(); /* Do stuff here with `ptr'. */ free(ptr); } return 0; } > I would like to not use fix- ed size arrays, as the real function > should be general enough to handle all kind of array sizes. Then pass the size of the array in a parameter. #include <sys/types.h> char * allocdata (size_t nbytes) { char *p; p = (char *) malloc(nbytes * sizeof(char)); return p; } int main (void) { char *a; char *b; a = allocdata(512); b = allocdata(1024); /* Do something with `a' and `b'. */ free(a); free(b); return 0; } Note that allocdata() as it is written above though reveals that your function is a plain wrapper around the malloc() library function. You can throw away the wrapper (saving you an extra function call) and write this as: int main (void) { char *a; char *b; a = malloc(512 * sizeof(char)); b = malloc(1024 * sizeof(char)); It is equally clear, and readable. Some will argue, more readable. > What is the best solution for this problem? The one you like most. -- Giorgos Keramidas - http://www.FreeBSD.org keramida@FreeBSD.org - The Power to Serve To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-questions" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020513235552.GB14825>