Simple C implementation for malloc / free memory tracking?

programming language: C platform: ARM Compiler: ADS 1.2

I need to track simple melloc/free calls in my project. I just need to get a general idea of โ€‹โ€‹how much heap memory is required when the program has allocated all its resources. So I provided a wrapper for malloc/free calls. In these shells, I need to increase the current amount of memory when malloc is called and decreases it when free is called. The malloc case is direct, as I have a size to allocate from the caller. I am wondering how to deal with the free tag, since I need to keep the location of the pointer / size somewhere. This is C, I do not have a standard card to implement this easily.

I am trying to avoid the link in some libraries, so I prefer the implementation of .c / h.

So, I wonder if there is already a simple implementation that I can lead to. If not, this is the motivation for implementation and implementation.

EDIT: Purely for debugging, and this code does not ship with the product.

EDIT: An initial implementation based on a response from Makis. I would appreciate feedback on this.

EDIT: revised implementation

 #include <stdlib.h> #include <stdio.h> #include <assert.h> #include <string.h> #include <limits.h> static size_t gnCurrentMemory = 0; static size_t gnPeakMemory = 0; void *MemAlloc (size_t nSize) { void *pMem = malloc(sizeof(size_t) + nSize); if (pMem) { size_t *pSize = (size_t *)pMem; memcpy(pSize, &nSize, sizeof(nSize)); gnCurrentMemory += nSize; if (gnCurrentMemory > gnPeakMemory) { gnPeakMemory = gnCurrentMemory; } printf("PMemAlloc (%#X) - Size (%d), Current (%d), Peak (%d)\n", pSize + 1, nSize, gnCurrentMemory, gnPeakMemory); return(pSize + 1); } return NULL; } void MemFree (void *pMem) { if(pMem) { size_t *pSize = (size_t *)pMem; // Get the size --pSize; assert(gnCurrentMemory >= *pSize); printf("PMemFree (%#X) - Size (%d), Current (%d), Peak (%d)\n", pMem, *pSize, gnCurrentMemory, gnPeakMemory); gnCurrentMemory -= *pSize; free(pSize); } } #define BUFFERSIZE (1024*1024) typedef struct { bool flag; int buffer[BUFFERSIZE]; bool bools[BUFFERSIZE]; } sample_buffer; typedef struct { unsigned int whichbuffer; char ch; } buffer_info; int main(void) { unsigned int i; buffer_info *bufferinfo; sample_buffer *mybuffer; char *pCh; printf("Tesint MemAlloc - MemFree\n"); mybuffer = (sample_buffer *) MemAlloc(sizeof(sample_buffer)); if (mybuffer == NULL) { printf("ERROR ALLOCATING mybuffer\n"); return EXIT_FAILURE; } bufferinfo = (buffer_info *) MemAlloc(sizeof(buffer_info)); if (bufferinfo == NULL) { printf("ERROR ALLOCATING bufferinfo\n"); MemFree(mybuffer); return EXIT_FAILURE; } pCh = (char *)MemAlloc(sizeof(char)); printf("finished malloc\n"); // fill allocated memory with integers and read back some values for(i = 0; i < BUFFERSIZE; ++i) { mybuffer->buffer[i] = i; mybuffer->bools[i] = true; bufferinfo->whichbuffer = (unsigned int)(i/100); } MemFree(bufferinfo); MemFree(mybuffer); if(pCh) { MemFree(pCh); } return EXIT_SUCCESS; } 
+10
c dynamic-memory-allocation
May 12 '09 at 10:10
source share
7 answers

You can select a few extra bytes in your wrapper and put either an identifier (if you want to be able to bind malloc () and free ()) or just size. Just malloc () is a lot more memory, store the information at the beginning of your memory block and move the pointer that you return that many bytes forward.

It can be, and btw is also easy to use for fence pointers / fingerprints, etc.

+12
May 12, '09 at 10:29 a.m.
source share

Either you can have access to the internal tables used by malloc / free (see this question: Where Do malloc () / free () Keep selected sizes and addresses? For some hints), or you need to manage your own tables in your packages.

+2
May 12 '09 at 10:23
source share

You can always use valgrind instead of doing your own implementation. If you are not interested in the amount of allocated memory, you can use an even simpler implementation: (I did it very quickly so that there might be errors, and I understand that this is not the most efficient implementation. PAllocedStorage should be provided with an initial size and an increase by some factor for resizing etc. but you get the idea.)

EDIT: I missed what it was for ARM. As far as I know, valgrind is not available in ARM, so this may not be an option.

 static size_t indexAllocedStorage = 0; static size_t *pAllocedStorage = NULL; static unsigned int free_calls = 0; static unsigned long long int total_mem_alloced = 0; void * my_malloc(size_t size){ size_t *temp; void *p = malloc(size); if(p == NULL){ fprintf(stderr,"my_malloc malloc failed, %s", strerror(errno)); exit(EXIT_FAILURE); } total_mem_alloced += size; temp = (size_t *)realloc(pAllocedStorage, (indexAllocedStorage+1) * sizeof(size_t)); if(temp == NULL){ fprintf(stderr,"my_malloc realloc failed, %s", strerror(errno)); exit(EXIT_FAILURE); } pAllocedStorage = temp; pAllocedStorage[indexAllocedStorage++] = (size_t)p; return p; } void my_free(void *p){ size_t i; int found = 0; for(i = 0; i < indexAllocedStorage; i++){ if(pAllocedStorage[i] == (size_t)p){ pAllocedStorage[i] = (size_t)NULL; found = 1; break; } } if(!found){ printf("Free Called on unknown\n"); } free_calls++; free(p); } void free_check(void) { size_t i; printf("checking freed memeory\n"); for(i = 0; i < indexAllocedStorage; i++){ if(pAllocedStorage[i] != (size_t)NULL){ printf( "Memory leak %X\n", (unsigned int)pAllocedStorage[i]); free((void *)pAllocedStorage[i]); } } free(pAllocedStorage); pAllocedStorage = NULL; } 
+1
May 12, '09 at 12:17
source share

I would use rmalloc . This is a simple library (actually itโ€™s just two files) for debugging memory, but it also supports statistics. Since you already have wrapper functions, it is very easy to use rmalloc for it. Keep in mind that you also need to replace strdup, etc.

0
May 12 '09 at 12:34
source share

Your program may also need to intercept realloc (), calloc (), getcwd () (since it can allocate memory when the buffer is NULL in some implementations), and possibly strdup () or a similar function, if supported by your compiler

0
May 12 '09 at 13:12
source share

If you are using x86 , you can simply run your binary under valgrind and this will collect all this information for you using the standard implementation of malloc and free . Plain.

0
May 13 '09 at 3:38
source share

I tested some of the same techniques that were mentioned on this page and got here from a Google search. I know this question is old, but I wanted to add for the record ...

1) Does your operating system show any tools to see how much heap memory is used in the current process? I see you are talking about ARM, so that may be so. On most full-featured operating systems, itโ€™s just a matter of using the cmd-line tool to view heap size.

2) If available in your libc, sbrk (0) on most platforms will tell you the final address of your data segment. If you have this, all you have to do is save this address at the beginning of your program (say startBrk = sbrk (0)), then at any time your allocated size will be sbrk (0) - startBrk.

3) If shared objects can be used, you dynamically bind to your libc, and your OS runtime loader has something like an LD_PRELOAD environment variable, you might find it more useful to create your own shared object that defines the actual libc with the same characters ( malloc (), not MemAlloc ()), and then the loader first loads your library and "inserts" the libc functions. You can also get the addresses of the actual libc functions with dlsym () and the RTLD_NEXT flag so that you can do what you do above without having to recompile all your code to use your malloc / free wrappers. This is just a run-time solution when you run your program (or any program that matches the description in the first sentence), where you set an environment variable, for example LD_PRELOAD = mymemdebug.so, and then run it. (google to host shared objects. This is a great technique and one is used by many debuggers / profilers)

0
Aug 01 '13 at 20:04 on
source share



All Articles