Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!spool.mu.edu!uunet!mcsun!goya!turia.dit.upm.es!esink From: esink@turia.dit.upm.es (Eric Wayne Sink) Newsgroups: comp.lang.c Subject: Question on Portable Memory Management Syntax Message-ID: <1991Feb18.133400.11870@dit.upm.es> Date: 18 Feb 91 13:34:00 GMT Sender: @dit.upm.es Reply-To: esink@turia.dit.upm.es (Eric Wayne Sink) Organization: Dept. Ingenieria de Sistemas Telematicos, dit, upm, Madrid, Spain Lines: 94 Nntp-Posting-Host: turia.dit.upm.es Here's a question for everyone. It's kind of subjective, so all opinions welcome. Please respond by posting (unless the question is inappropriate) as I usually do read this newsgroup. :-) Given : There is a piece of software which must be portable between the Macintosh, and some more generic platform. For those of you unfamiliar with programming on the Mac, the following will explain the constraint of the problem : The Mac memory manager performs an order of magnitude better if most or all dynamically allocated blocks of memory are allocated as 'handles' instead of pointers. A handle is pointer to a master pointer. The Memory manager reserves the right to move your block of memory at well defined times. When it does so, the master pointer is changed. For this reason, most programs which allocat lots of memory at runtime look like this on the Mac : struct mystruct **theHandle; theHandle = NewHandle(sizeof(struct mystruct)); (*theHandle)->someMember = whatever; instead of the usual : struct mystruct *thePointer; thePointer = malloc(sizeof(struct mystruct)); thePointer->someMember = whatever; The crucial issue here is finding a syntax for referencing struct members. This syntax must be usable on both platforms. The piece of software in question allocates a LOT of memory at run time. In order to handle portability as described above, I see 3 possible solutions, each with advantages and disadvantages : 1. Always use malloc. This will result in HORRIBLE performance on the Macintosh, so I consider this option out of the question. Please, no flames about the Mac Memory Manager. 2. Always use handles. This is done by implementing a simple version of the Mac memory manager by using malloc. Each call to NewHandle allocates the correctly sized block with a malloc call, and allocates a master pointer, also with malloc, setting that pointer to point to the block, and returns the address of the master pointer. (Of course, this memory manager is not going to go moving blocks around like the Mac does.) Disadvantages here are that every struct reference potentially involves an extra redirection on a platform which does not need it. An advantage is that I would probably not merely allocate a master pointer, but would allocate a small struct containing the master pointer as well as the size of the block, so better memory usage statistics could be kept. An example implementation of a very simple NewHandle : void **NewHandle(long size) { void **result; result = malloc(sizeof(void *)); *result = malloc(size); return result; } 3. Use the preprocessor to allow usage of the best method for each platform. In this case, we do something like the following : #ifdef MAC #define STRUXMEMBER(s,m) ((*s)->(m)) typedef struct mystruct **BLOCKHP; #else #define STRUXMEMBER(s,m) ((s)->(m)) typedef struct mystruct *BLOCKHP; #endif Then, every struct reference looks like this : BLOCKHP GetMemoryBlock(long size); /* The definition of GetMemoryBlock has #ifdef's to return the correct type. */ BLOCKHP theRef; theRef = GetMemoryBlock(sizeof(struct mystruct)); STRUXMEMBER(theRef,someMember) = whatever; Option 2 introduces inefficiency into the program. Option 3 introduces undesirable syntactic changes to the source. Which is better ? Is the method of option 3 too ugly ? Are there compromises worth considering ? Any and all comments appreciated. Eric W. Sink | Putting the phrase |All opinions Departamento de Telematica | "Frequently Asked" |are mine and Universidad Politecnica de Madrid| in your kill file is |not necessarily esink@turia.dit.upm.es | not recommended. |yours.