Malloc problems

Ken Raeburn raeburn at athena.mit.edu
Mon May 23 20:59:01 AEST 1988


In article <13100010 at bucc2> brian at bucc2.UUCP writes:
>  For the reasons outlined in Caplinger's paper, it is often difficult
>to free() everything that has gotten *alloc()'d in a large project.
>We do not want to implement garbage collection, however, due to
>the code overhead and lack of sources. The environment we are running
>is Microsoft C 5.0 on IBM AT's and PS/2's under MS-DOSN'T.
>
>  An additional field will be added to the header at the beginning of
>every block on the heap. After a call to malloc is made, a mark() function
>can be called to set a code in this field. Later, a function called
>free_group() frees all the blocks with a specific code. The functions
>would look like this:
>
>/* mark a pointer to a block allocated from the heap. returns ptr on	*/
>/* success, or NULL if ptr didn't point into the heap.			*/
>char *mark(ptr, code)
>  char *ptr;			/* block to mark			*/
>  long code;			/* code number to mark with		*/
>
>/* free all blocks on the heap with a specified mark code. Returns a	*/
>/* count of the number of blocks free'd.				*/
>int free_group(code)
>  long code;			/* code number of blocks to free	*/

How about combining these steps?  Or letting the allocator dynamically
assign the code number?  I think PL/I does something like this.  (Or
was it just Multics PL/I?)  The allocator is part of the language, so
you could have something like:

	declare bar area;
	allocate foo in bar;

Later, everything in bar could be freed.  The area could also be
declared as extensible, so that if you ran out of the space already
allocated, the allocator would go find more, and use it also under the
name of bar.

(I don't remember the details, and I didn't use it much, so I may have
some of this wrong.  There were some sort of inconsistencies between
the pure PL/I versions and some system subroutines available.)

A C/UNIX variant could probably be implemented with an internal design
similar to what you're already doing.

	typedef struct _area {
		struct _area *next;
		/* data relating to allocations */
	} *area;

	area create_area (void);
	void * allocate (size_t size, area a);
	void release (void * ptr);
	void free_area (area a);

>   Each programmer will have a unique code similar to a UID, which will be
>stored in the programmer field. This will help in finding a scapegoat when
>problems arise... errrr rather in locating the code that isn't freeing
>its allocated memory. Since we only have about 15 programmers doing this
>type of work, 64 programmer codes per project should be sufficient.
>
>  The project field will be a code indicating which project or library
>allocated the block.

Umm... I wouldn't be interested in knowing which programmer, except to
go beat him over the head later.  The library, and perhaps the source
file, would be useful information, but how can this be managed on a
large scale?  If I log into your system where some of the installed
libraries use this scheme, or if you're interested in exporting it to
other sites, how can conflicts be avoided?  I'd prefer some way of
avoiding conflicts, or at least detecting them sometime (compile- or
link-time preferably, run-time is permissible).

>  Sixteen bits are reserved for the code itself, allowing for 2^16 
>"memory" groups per programmer per project. Additionaly, to help with
>coding reentrant functions, a gensym() function will return a unique
>code number. To make gensym() codes seperate from codes defined by
>the programmer, the gensym flag is provided in the structure.

Now that's sounding better.  Can the gensym function be used
throughout?  (I hope you're not really calling it "gensym" -- it would
seem to be too generic a name.  I've used it in several different
programs for various things -- not libraries, but programs where name
conflicts wouldn't result.)



More information about the Comp.lang.c mailing list