how do you know 'free' freed?

Gary Bridgewater gary at dgcad.SV.DG.COM
Mon Oct 16 19:31:30 AEST 1989


In article <11275 at smoke.BRL.MIL> gwyn at brl.arpa (Doug Gwyn) writes:
>In article <5521 at hacgate.UUCP> howard at aic.dpl.scg.hac.com (Mike Howard (213)317-5690) writes:
>>There must be some way to confirm free.
>No, in general free() always works (assuming you have given it a valid
     ^^ ^^^^^^^
>pointer that was malloc()ed) and there is no point in trying to see if
                                  ^^^^^ ^^ ^^ ^^^^^
>it worked.

*BEEP*
Time's up. The original poster gave us the vital clue - Sun 4.0.something.
The correct answer is "malloc/free is somewhat broken in Sunos 4.0.1-3".
This has been mentioned before, in a Feb. Sun Spots article - here it is...

-=-=-=-=-=-=-==-=-
X-Sun-Spots-Digest: Volume 7, Issue 127, message 3 of 16

Fellow Spotters, I need your help.

A friend of mine has been developing a program which is a kind of
architectural CAD package.  Not being an architect, I'm not sure what one
might do with it, but it produces some pretty pictures in the process.
This program is having problems with malloc.

To start with, we are dealing with Sun 3's of various flavors, all with
color tubes.  They are running SunOS 3.4, using SunView, and SunCore.  The
programming is in C.

Malloc!!  Boy, what a mess.  Muses (the package mentioned above) maintains
a large number of linked lists, malloc'ing and free'ing space for nodes as
needed.  There is a LOT of malloc'ing and free'ing going on, and nodes
come in only a few sizes.  This last point is important.  Imagine the
following code fragment:

	node1 = malloc(N);
	node2 = malloc(N);
	free(node1);
	node3 = malloc(N);

Node3 does not get the memory which node1 released.  Instead, malloc asks
the system for additional memory to satisfy the malloc.  This is BUSTED!
Muses does a *****LOT***** of this, and grows and grows and grows in
memory, even though it may not need to.  Eventually, muses crashes, with
the program counter usually pointing into malloc.

I fetched the malloc replacement written by Bill Sebok at Princeton
University and plugged that in, but it didn't help tremendously because
something in SunCore and/or SunView seems to be calling variants of malloc
(calloc is one that comes to mind) and those suck up memory and crash.

Does anyone have a solution?  Upgrading to SunOS 4.0[.1] is not helpful
because the malloc problem still exists there.  In fact, here is a nice
little program which shows it.  (I sent in a bug report to sunbugs a day
or two ago, but haven't heard anything back.  Besides, I think we only
have update service, so they probably threw it into the trash.)

__________cut here for program
/*
 * NAME
 *	mtest - test memory allocation.
 *
 * COMPILATION
 *	cc -o mtest mtest.c
 *
 * SYNOPSIS
 *	mtest
 *
 * DESCRIPTION
 *	mtest demonstrates that malloc is broken.  Specifically, that
 *	malloc is not smart enough to use a piece of memory of exactly
 *	the right size when it is available (unless it is at the end
 *	of memory).
 */
#include <stdio.h>
#include <sys/errno.h>
#include <sys/types.h>

#define	BIGBUF		1000000	/* 1 MBytes */
#define SMALLBUF	10240	/* 10 KBytes */

char	*malloc();
caddr_t	sbrk();
extern int errno;

main()
{
	char	*buf1, *buf2;	/* buffer pointers */
	caddr_t	topmem;		/* upper limit of memory */

	printf("beginning memory allocation test\n");
	printf("All values are reported in decimal.\n");
	topmem = sbrk(0);
	printf("The end of memory is initially at %d\n\n",(int) topmem);

	/*
	 * Demonstrate that you can (sometimes) re-use memory which has
	 * been malloc'ed and subsequently free'd.
	 */
	buf1 = malloc(BIGBUF);
	if (buf1 == 0) {
		perror("test");
		errno = 0;
		exit(1);
	}
	else {
		printf("requested %d bytes of memory\n", BIGBUF);
		topmem = sbrk(0);
		printf("The end of memory is now at %d\n", (int) topmem);
	}

	if (free(buf1) == 0) {
		perror("test");
		errno = 0;
		exit(2);
	}
	else {
		printf("%d bytes of memory freed\n", BIGBUF);
		printf("There is now a %d byte piece of memory available.\n", BIGBUF);
		topmem = sbrk(0);
		printf("The end of memory is still at %d\n", (int) topmem);
	}

	buf1 = malloc(BIGBUF);
	if (buf1 == 0) {
		perror("test");
		errno = 0;
		exit(1);
	}
	else {
		printf("requested another %d bytes of memory -- ", BIGBUF);
		printf("Should use available space.\n");
		topmem = sbrk(0);
		printf("The end of memory is still at %d\n\n", (int) topmem);
	}

	/*
	 * Now demonstrate that if a block of free memory is surrounded
	 * by other chunks of memory, then a memory request of that size
	 * will NOT use the available piece.
	 */
	buf2 = malloc(SMALLBUF);
	if (buf2 == 0) {
		perror("test");
		errno = 0;
		exit(1);
	}
	else {
		printf("Requested %d bytes of memory.\n", SMALLBUF);
		topmem = sbrk(0);
		printf("The end of memory is now at %d\n", (int) topmem);
	}

	if (free(buf1) == 0) {
		perror("test");
		errno = 0;
		exit(2);
	}
	else {
		printf("Freed %d bytes of memory.\n", BIGBUF);
		printf("There is now a %d byte piece of memory available.\n", BIGBUF);
		topmem = sbrk(0);
		printf("The end of memory is still at %d\n", (int) topmem);
	}

	buf1 = malloc(BIGBUF);
	if (buf1 == 0) {
		perror("test");
		errno = 0;
		exit(1);
	}
	else {
		printf("Requested another %d bytes of memory -- ", BIGBUF);
		printf("Should use available space.\n");
		topmem = sbrk(0);
		printf("WHOA!  The end of memory is now at %d\n",(int) topmem);
	}

	exit(0);
}
__________cut here for program

Please email responses to me, it will be quicker than posting to
sun-spots.  I'll post a summary if anyone requests it.  In the mean time,
how can Sun, or any vendor, allow malloc and co. to be so busted?  It
boggles my mind.

William Reeder, University of Texas, Computation Center
ARPA: reeder at emx.utexas.edu	UUCP: ..!uunet!cs.utexas.edu!ut-emx!reeder
BITNET: CCCD001 @ UTA3081
-=-=-=-=-=-=-==-=-

And it's still that way in 4.0.3
-- 
Gary Bridgewater, Data General Corp., Sunnyvale Ca.
gary at sv4.ceo.sv.dg.com or 
{amdahl,aeras,amdcad,mas1,matra3}!dgcad.SV.DG.COM!gary
No good deed goes unpunished.



More information about the Comp.lang.c mailing list