[comp.lang.c] Turboc 2.0 malloc/free/coreleft

bloomqui@osiris.cso.uiuc.edu (Kim Bloomquist) (01/31/91)

I'm trying to write a Turbo C 2.0 program on a Zenith 386 that
reports the amount of memory (RAM) available after performing
certain operations.  The following program produces the output 
shown below:

---------------------------- tst.c --------------------------
#include <stdio.h>
#include <stdlib.h>
#include <alloc.h>
main()
{
	unsigned long n;
	char *s;

	n = coreleft();
	printf("ram left = %lu bytes free\n", n);
	if ((s = (char *) malloc(80)) == NULL)
	{
		printf("allocation failed\n");
		exit(0);
	}
	printf("buffer allocated\n");
	n = coreleft();
	printf("ram left = %lu bytes free\n", n);
	/* printf("string: ");
	gets(s); */
	free((void *) s);
	printf("buffer deallocated\n");
	n = coreleft();
	printf("ram left = %lu bytes free\n", n);
}

output from run 1: /* commented version */

ram left = 63704 bytes free
buffer allocated
ram left = 63616 bytes free
buffer deallocated
ram left = 63704 bytes free

The program performs as expected.  Memory is allocated to hold s then
free() deallocates s making available the same number of bytes (63,704)
we started with.  However, when the comments are removed from around the
printf/gets statements the following output is produced.  The last call
to coreleft shows only 63,082 bytes free and not the original 63,690 bytes.
Question 1:  What is being allocated to the missing 608 bytes?
Question 2:  Can this memory (the 608 bytes) be deallocated?

output from run2: /* uncommented version */

ram left = 63690 bytes free
buffer allocated
ram left = 63602 bytes free
string: 
buffer deallocated
ram left = 63082 bytes free

emigh@ncsugn.ncsu.edu (Ted H. Emigh) (02/01/91)

In article <1991Jan30.172158.2769@ux1.cso.uiuc.edu > bloomqui@osiris.cso.uiuc.edu (Kim Bloomquist) writes:
 >I'm trying to write a Turbo C 2.0 program on a Zenith 386 that
 >reports the amount of memory (RAM) available after performing
 >certain operations.  The following program produces the output 
 >shown below:
 >
 >---------------------------- tst.c --------------------------
 >#include <stdio.h>
 >#include <stdlib.h>
 >#include <alloc.h>
 >main()
 >{
 >	unsigned long n;
 >	char *s;
	char t[80];      /*   ADD THIS LINE   */
 >
 >	n = coreleft();
 >	printf("ram left = %lu bytes free\n", n);
        printf("string t: ");
	scanf(t);
	n = coreleft();
	printf("ram left = %lu bytes free\n", n);
 >	if ((s = (char *) malloc(80)) == NULL)
 >	{
 >		printf("allocation failed\n");
 >		exit(0);
 >	}
 >	printf("buffer allocated\n");
 >	n = coreleft();
 >	printf("ram left = %lu bytes free\n", n);
 >	printf("string: ");
 >	gets(s);
 >	free((void *) s);
 >	printf("buffer deallocated\n");
 >	n = coreleft();
 >	printf("ram left = %lu bytes free\n", n);
 >}


This slight modification will give you the correct answers.  A couple of points

1)  coreleft() does not return the number of bytes available for malloc'ing.
    What it does return is the number of bytes below the lowest allocated
    block.  To test this, malloc a huge chunk, then a small chunk.  free the
    large chunk.  coreleft will still give a small number.  You can even
    malloc some more without coreleft changing!!!

2)  For Turbo-C (and possibly others), stdin is not opened until the first
    reference to it.  Opening a file (and stdin/stdout) takes some space off
    the heap.

4)  If you have TC++, you can use the heapwalk functions to get a better idea
    of memory available, although it will not be contiguous.  This may or may
    not be particularly useful.

enag@ifi.uio.no (Erik Naggum) (02/01/91)

In article <1991Jan30.172158.2769@ux1.cso.uiuc.edu> bloomqui@osiris.cso.uiuc.edu (Kim Bloomquist) writes:

   The program performs as expected.  Memory is allocated to hold s then
   free() deallocates s making available the same number of bytes (63,704)
   we started with.  However, when the comments are removed from around the
   printf/gets statements the following output is produced.  The last call
   to coreleft shows only 63,082 bytes free and not the original 63,690 bytes.
   Question 1:  What is being allocated to the missing 608 bytes?
   Question 2:  Can this memory (the 608 bytes) be deallocated?

printf and gets are stdio routines, which allocate buffer space for
hitherto unused streams.  See setbuf(3) for a way to disable that.

BTW, since this buffer space allocation occurs after your allocation,
the free may not actually release any memory because your allocated
block is no longer the "top-most" allocated block.  Your "608 bytes"
may thus be inaccurate.

--
[Erik Naggum]	Snail: Naggum Software / BOX 1570 VIKA / 0118 OSLO / NORWAY
		Mail: <erik@naggum.uu.no>, <enag@ifi.uio.no>
My opinions.	Wail: +47-2-836-863	Another int'l standards dude.