3

I would like to get the total memory allocated before and after I call a function in order to determine if I have freed everything correctly or not.

I'm doing this in C and I'm very rusty so forgive me if this is a naive question. I'm looking for something similar to the C# GC.GetTotalMemory(true) and this is in Windows for now.

Right now I am using PROCESS_MEMORY_COUNTERS_EX and GetProcessMemoryInfo(...), before and after calling the function but I can't make heads or tails of the output because if I go into the function and comment out a call to free(...) then it will give me the same results (after is always larger). Here is what I have right now...

GetProcessMemoryInfo(hProc, &before, sizeof(before));
r = c->function();
GetProcessMemoryInfo(hProc, &after, sizeof(after));

if(r->result != 0) {
    printf("error: %s\r\n", c->name);
    printf("  %s\r\n", r->message);
    printf("  %s (%d)\r\n", r->file, r->line);
    failed++;
}
else if(after.PrivateUsage > before.PrivateUsage) {
    printf("memory leak: %s\r\n", c->name);
    printf("  %d kb\r\n", after.PrivateUsage - before.PrivateUsage);
    failed++;
}
else succeeded++;

With a result like this:

after.PrivateUsage - before.PrivateUsage = 12288

If I go and comment out some calls to free I get the same result. How can I actually determine the current total size of memory that I have allocated using malloc?

justin.m.chase
  • 13,061
  • 8
  • 52
  • 100
  • are you trying to detect memory leaks or keep track of memory use for some sort of performance metrics? – Gabriel Southern May 06 '12 at 18:36
  • Memory leaks, but now that you mention it... I'm actually just writing tests for my code and I want to make sure that I have freed everything. I want to make sure the code is airtight. – justin.m.chase May 06 '12 at 22:21
  • I haven't used it, but I read that Visual Studio has a feature called the CRT Debug Heap that sounds like it's what you want: http://msdn.microsoft.com/en-us/library/974tc9t1(v=vs.85).aspx It might be more robust to use existing functionality than to create your own version. But I don't program in Windows so I can say for sure if this is what you want. – Gabriel Southern May 07 '12 at 01:44

3 Answers3

5

I am, not aware of any c standard library functions which can help you achieve this. AFAIK, there don't exist any. But you can use some sort of an hack, One should not use this in release builds but for debug and diagnostic purpose only.

You can use what I call malloc overloading in c. You do this with the help of macros.
You can write an wrapper function over malloc, without modifying each and every instance in your code where the function is called then a simple macro shall suffice:

void* my_malloc(size_t size, const char *file, int line, const char *func)
{

    void *p = malloc(size);
    printf ("Allocated = %s, %i, %s, %p[%li]\n", file, line, func, p, size);

    /*Link List functionality goes in here*/

    return p;
}

#define malloc(X) my_malloc( X, __FILE__, __LINE__, __FUNCTION__)

Inside your own function you can collect the diagnostics in some global data structure, say a linked list. For ex: It can maintain, buffer address being returned, the size for that corresponding allocation etc.
Similarly, you overload free() and you can do the bookkeeping in there, Each buffer address passed in to the function can be checked against the list items and removed from the list as and when a match is found.
At the end of the program the list contains entries for memory that was allocated but never freed, aka memory leaks. You can provide some api to fetch the diagnostic details from the list maintained whenever required.

You can often use this trick to write your own memory leak detector etc, for debugging purposes.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 3
    Your `#define malloc` needs to come after the definition of `my_malloc`. – Thomas Eding May 06 '12 at 18:34
  • I was actually considering doing this but I thought I must be missing something obvious :( Unless someone can come up with a better idea I will probably do this actually. – justin.m.chase May 06 '12 at 18:35
3

I did something like this years ago (before these great days of Stack Overflow!) by using my own malloc and free functions that recorded some metrics before and after calling the real malloc and free functions.

You could do something like this, which is not platform-dependent:

// in some common header file, let's say mem_metrics.h
#define malloc malloc_with_metrics
#define free   free_with_metrics

extern size_t num_current_allocs;
void* malloc_with_metrics(size_t size);
void free_with_metrics(void* ptr);


// in mem_metrics.c
#undef malloc
#undef free

size_t num_current_allocs = 0;

void* malloc_with_metrics(size_t size)
{
    ++num_current_allocs;
    return malloc(size);
}

void free_with_metrics(void* ptr)
{
    --num_current_allocs;
    free(ptr);
}

The example above records how many allocations are present at any given time, by accessing num_current_allocs. You can expand on this idea by recording whatever metrics you find useful! I often use it to make sure num_current_allocs is 0 when a program exits.

Another example: I once used something like this to find some un-freed bytes by keeping a table of pointers and their corresponding size in bytes, adding new pointers and their size when malloc_with_metrics was called and removing them when free_with_metrics was called.

If you need a lot of runtime metrics, there are much better and more thorough third-party libraries etc. that give a lot more information; however, this is a quick little trick when you need to check something in a pinch.

inspector-g
  • 4,146
  • 2
  • 24
  • 33
0

You can use Valgrind to check if you have freed all your dynamically allocated memory on process exit.

SigueSigueBen
  • 153
  • 1
  • 6