From owner-freebsd-questions Mon May 13 16:56:30 2002 Delivered-To: freebsd-questions@freebsd.org Received: from mailsrv.otenet.gr (mailsrv.otenet.gr [195.170.0.5]) by hub.freebsd.org (Postfix) with ESMTP id 4A66237B406 for ; Mon, 13 May 2002 16:56:20 -0700 (PDT) Received: from hades.hell.gr (patr530-a145.otenet.gr [212.205.215.145]) by mailsrv.otenet.gr (8.12.3/8.12.3) with ESMTP id g4DNtwVU012534; Tue, 14 May 2002 02:56:09 +0300 (EEST) Received: from hades.hell.gr (hades [127.0.0.1]) by hades.hell.gr (8.12.3/8.12.3) with ESMTP id g4DNtuBA015720; Tue, 14 May 2002 02:55:56 +0300 (EEST) (envelope-from keramida@ceid.upatras.gr) Received: (from charon@localhost) by hades.hell.gr (8.12.3/8.12.3/Submit) id g4DNtrZd015719; Tue, 14 May 2002 02:55:53 +0300 (EEST) (envelope-from keramida@ceid.upatras.gr) Date: Tue, 14 May 2002 02:55:52 +0300 From: Giorgos Keramidas To: Paul Everlund Cc: freebsd-questions@FreeBSD.ORG Subject: Re: C malloc question Message-ID: <20020513235552.GB14825@hades.hell.gr> References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.3.99i Sender: owner-freebsd-questions@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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 2 #include You're missing 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 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