ecollins@NMSU.EDU (08/16/90)
Summary: A couple of weeks ago I posted a question concerning the message: Error: Cannot perform realloc. Since several people expressed interest and since the information is generally useful I've included the best response and some example code. Symptoms(from initial posting): I have a good sized Athena Widget based program which creates toplevelshells for things such as help and various other options. If I select one of these options as soon as the initial screen comes up then the toplevelshells are created and everything works fine. I can make use of the functions provided by these shells for the remainder of the program and I can pop the shells down at any time without a problem. If I do some text processing ( including message passing with a Prolog process using named pipes ) and then try to use one of the options that generate a new toplevelshell I get the following message: Error: Cannot perform realloc. Sometimes I get the error, sometimes I don't, but typically I'll get a core dump at this point. If I don't select a toplevelshell option the program runs fine. I only allocate memory dynamically in one place and I'm sure that I free it properly when I'm done with it. I find it hard to believe that I'm running out of virtual memory... 1. Is there a way to programmatically monitor the available free memory as I execute the program so that I can see where memory is being used up? How? 2. I'm declaring several large character arrays inside lower level functions. Is it more memory efficient to declare these as global static arrays rather than auto arrays local to the function? 3. Are there certain types of programming errors that typically cause the above problem? ---------------------------------------------------------- Here is the most useful response I received: From: kay@cs.jhu.edu (Jon Kay) To: ecollins@nmsu.edu Subject: Error: Cannot perform realloc. To me, that message translates to the following: "Hey, Mr. Programmer! You have a stray pointer, and it's messing with my (malloc's) internal data structures!" If you are running under System V or SunOS, there is a nifty function called malloc_verify() which will make sure that the current malloc data structure is consistent. You can use this to track down the exact location of the bug (it's really great!). The manual pages to read are malloc(3) under SunOS and malloc(3X) under System V. You can nail down the exact amount of memory that has been used so far via the following incantaion: printf("%d bytes used\n", sbrk(0) - &end); Declare "extern char end;" in each such file (end is defined by ld to be the end of the program before any memory is malloc'ed. Read the sbrk(2) and end(3) manual pages for more information). Auto arrays are intrinsically more efficient if you can get away with them (they are nice because of the automatic and painless deallocation), but depending on the OS you can get into trouble if they are very large (say, 10K. Possibly less on older Unices). ---------------------------------------------------------------------------- Good advice. Thanks Jon, for answering q's 1, 2 and more. I got rid of my problem by cleaning up several functions and replacing a large chunk of code -- including my malloc/free code. I never did narrow it down to an exact statement. Here's one possible cause for q3: I had an error in some code that dealt with a radio group of toggle widgets ( Athena ). When you select a member of a radio group, all callbacks registered for the previously selected member get called along with actions and callbacks for the newly selected member. I allocated in the callback of the first selected toggle button and deallocated the second time it was entered. Unfortunately, my flagging mechanism did not catch all possible cases and it was possible to come up with mismatched mallocs and frees. In any case I cleaned that code up and opted for a static char array instead of malloc/free. I suspect this to have been my problem. Here's some generally useful code based on Jon's recommendations and malloc(3). /*========================================================================= ** ** memtest -- ** Example code to show the use of memory allocation routines. ** ** Notes: ( SunOS 4.1 ) ** Depends on malloc.o and mallocmap.o files from /usr/lib/debug. ** ** See malloc(3) for more info. ** ** Makefile: ** CC = /bin/cc ** CFLAGS = -target sun3 ** memtest: memtest.c ** $(CC) $(CFLAGS) -o memtest memtest.c malloc.o mallocmap.o ** ** Modification Author Date Description ** ------------ ------ ---- ----------- ** --- EMC, NMSU 29-Jul-90 original ** **======================================================================*/ #include <stdio.h> #include <sys/types.h> void ShowMemUsed(); void SetMallocDebugLevel(); void CheckMalloc(); void DisplayHeapMap(); /*==============================*/ main() { caddr_t sbrk(); extern char end; char *buffer0, *buffer1, *buffer2; ShowMemUsed( "Before any mallocs" ); DisplayHeapMap(); SetMallocDebugLevel( 2 ); ShowMemUsed( "After setting malloc debug level" ); buffer0 = ( char * ) malloc( 10 ); ShowMemUsed( "After one 10 byte malloc" ); CheckMalloc(); buffer1 = ( char * ) malloc( 17000 ); ShowMemUsed( "After a second malloc of 17000 bytes" ); DisplayHeapMap(); } /*==============================*/ void ShowMemUsed( message ) char *message; { caddr_t sbrk(); extern char end; printf( "\n%s: %d bytes used\n", message, sbrk(0) - &end ); } /*==============================*/ void DisplayHeapMap() { printf("\n==============================\nStart of Heap Map:\n" ); mallocmap(); printf("End of Heap Map.\n==============================\n" ); } /*==============================*/ void SetMallocDebugLevel( level ) int level; { int oldLevel; oldLevel = malloc_debug( level ); printf( "\nOld Malloc debug level: %d\nNew Malloc debug level: %d\n", oldLevel, level ); } /*==============================*/ void CheckMalloc() { printf( "\nChecking malloc structure for errors...\n" ); if ( malloc_verify() ) printf( "No errors were found.\n" ); else printf( "Errors were detected!\n" ); } Also, thanks go to Mark Leisher for suggesting the use of Xscope. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= = Mike Collins | "Why would I want to change my = = New Mexico State University | mind? Is there something wrong = = e-mail: ecollins@nmsu.edu | with the one I have?" -- Spock = =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=