[comp.sys.ibm.pc] Freeing allociated memory.

jamesd@resrch.molienergy.bc.ca (James Dudley) (01/11/90)

Hello to all:

I am experiencing a problem with freeing memory allociated which was
allociated with malloc().   Consider the following code.

char *buf, *lineptr[2000];

if (buf = (char *) malloc(fsize*sizeof(char)) == NULL)  {
   print error message and return
}
lineptr[0] = buf;
     do stuff
/* now free allociated memory */
free((void *) buf);

Free() doesnot appear to deallociate the memory because I am using a 
routine to traverse the Heap and report back Free and Unused blocks.

Using MSC 5.1  compiled with Small memory model.
Any ideas?

Thanks in advance for any help on this.

James
     

-- 
James Dudley					jamesd@MoliEnergy.BC.CA
Moli Energy Ltd.				...!ubc-cs!van-bc!resrch!jamesd
Burnaby, B.C. CANADA

pipkins@qmsseq.imagen.com (Jeff Pipkins) (01/12/90)

In article <1990Jan10.202458.17223@resrch.molienergy.bc.ca> jamesd@resrch.molienergy.bc.ca (James Dudley) writes:
>Hello to all:
>
>I am experiencing a problem with freeing memory allociated which was
>allociated with malloc().   Consider the following code.
>
>char *buf, *lineptr[2000];
>
>if (buf = (char *) malloc(fsize*sizeof(char)) == NULL)  {
>   print error message and return
>}
>lineptr[0] = buf;
>     do stuff
>/* now free allociated memory */
>free((void *) buf);
>
>Free() doesnot appear to deallociate the memory because I am using a 
>routine to traverse the Heap and report back Free and Unused blocks.
>

The problem is not with free().  The memory is allocated, but the variable
buf will not point to it!  In the "if" statement above, the == operator
has higher precedence than the = operator.  The memory will be allocated
and then the pointer returned will be compared to NULL.  If the request
is granted, the comparison will be false, and so the value of 0 will be
assigned to buf, effectively making it a NULL pointer.  The call to free()
will then try to free memory that has not been allocated with malloc(),
and the block allocated by malloc() will, of course, remain.  Also note
that free(NULL) can cause disastrous results, and should be regarded as "BAD".

To avoid this mess, just add another set of parentheses, like so:

   if ( (buf = (char *) malloc(fsize*sizeof(char)) ) == NULL) 
	^                                          ^

Hope this helps!

georgemartin@hodgenet.UUCP (George H. Martin) (01/12/90)

In article <1990Jan10.202458.17223@resrch.molienergy.bc.ca> jamesd@resrch.molienergy.bc.ca (James Dudley) writes:
>
>I am experiencing a problem with freeing memory allociated which was
>allociated with malloc().   Consider the following code.
>
>char *buf, *lineptr[2000];
>
>if (buf = (char *) malloc(fsize*sizeof(char)) == NULL)  {
>   print error message and return
>}
>lineptr[0] = buf;
>     do stuff
>/* now free allociated memory */
>free((void *) buf);
>
>Free() doesnot appear to deallociate the memory because I am using a 
>routine to traverse the Heap and report back Free and Unused blocks.
>
>Using MSC 5.1  compiled with Small memory model.
>Any ideas?
>

In the UNIX/'C' environment:

The free(3c) libc function call NEVER returns the calling program's data space
to the operating system. Once space is allocated through sbrk(2) system calls
during a program's call to malloc, it is NEVER returned. The free(3c) function
removes the memory to be freed from the programs virtual memory, but retains
the actual data space for possible future reallocation (in whole or in part) by
subsequent calls to malloc. 

To maintain control of your data space, you must utilize the sbrk(2) and brk(2)
system calls to actively, dynamically manipulate it. These calls allow you to
mainpulate the break value of the program; the end of the data space (data
segment in DOS terms). Of course, this assumes the MSC 5.1 environment 
supports these calls. Turbo C does. To what extent the free(3c) call performs
in a 'C'DOS environment as it does in a UNIX environment, I do not know.

NOTE: At least in UNIX. you never should malloc for space and then do a brk(2)
or sbrk(2) to free it. Obviously, the tables maintained by malloc for its
housekeeping will not be updated if you do this. The next time you call malloc
your program will likely crash due to a "corrupt arena".

Just some background. Hope it helps.

-- 
George H. Martin
uunet!hodgenet!georgemartin
Homer Dodge Network Systems, Inc.
+1 201 454 3333