Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!bloom-beacon!athena.mit.edu!raeburn From: raeburn@athena.mit.edu (Ken Raeburn) Newsgroups: comp.lang.c Subject: Re: Re: Malloc problems Message-ID: <5482@bloom-beacon.MIT.EDU> Date: 23 May 88 10:59:01 GMT References: <690008@hpfelg.HP.COM> <13100010@bucc2> Sender: daemon@bloom-beacon.MIT.EDU Reply-To: raeburn@athena.mit.edu (Ken Raeburn) Organization: Massachusetts Institute of Technology Lines: 83 In article <13100010@bucc2> brian@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.)