Memory allocation test in C - How to write a CUnit-Test for malloc and free?

since a few days I am stuck with a Test for one of my applications that i can't fix. So i decide to write a test for my test...

I want to allocate memeory, watch the grown of the memory in use and than free the memory again. I excpect that the allocated memory is not in use anymore, right?

I am working on Mac OSX (10.6.8) and gcc (GCC) 4.2.1

so i write this test:

void testMemoryFreeCheck(){
    puts("- test Memory Free Check  -");
    puts("- ----------------------- -");
    puts("- This test takes a while -");
    puts("");
    struct rusage rus;
    getrusage(RUSAGE_SELF, &rus);

    // Things befor we want to mature. 
    char *holder[10000];
    char *bigHolder;
    int loops =  10000;
    int i;

    // Variables used for tests. 
    long int afterFirstTestKiloByte = 0;
    long int afterSecondTestKiloByte = 0;
    long int afterThirdTestKiloByte = 0;
    long int afterForuthTestKiloByte = 0;

    getrusage(RUSAGE_SELF, &rus);
    long int initialKiloByte = rus.ru_maxrss;
    printf("Initial KB Used: %ld\n", initialKiloByte);

    // a adder to proof that we get it write
    char add = "A";
    getrusage(RUSAGE_SELF, &rus);
    long int afterAddKiloByte = rus.ru_maxrss;
    printf("After a char add KB Used: %ld\n", initialKiloByte);
    getrusage(RUSAGE_SELF, &rus);
    long int growingKiloByte = rus.ru_maxrss;

    // This loop should do nothing.
    for(i=0; i<loops; ++i){
        printf(".");
    }
    puts("");
    getrusage(RUSAGE_SELF, &rus);
    afterFirstTestKiloByte = rus.ru_maxrss;
    printf("First Test should be 0 : %ld\n", (afterFirstTestKiloByte - afterAddKiloByte));
    CU_ASSERT_TRUE( (afterFirstTestKiloByte - afterAddKiloByte) == 0);

    // This loop should free all allocated space.
    for(i=0; i<(loops * 128); ++i){
        char *tmp = malloc(1024 * 1024);
        free(tmp);
    }

    getrusage(RUSAGE_SELF, &rus);
    afterSecondTestKiloByte = rus.ru_maxrss;
    printf("Second Test should be 0 (4096 is ok for some reasons): %ld\n", (afterSecondTestKiloByte - afterAddKiloByte));
    CU_ASSERT_TRUE( (afterSecondTestKiloByte - afterAddKiloByte) <= 4096);

    // This loop should increase the allocated space.
    for(i=0; i<loops; ++i){
        holder[i] = malloc(1024 * 1024);
    }
    getrusage(RUSAGE_SELF, &rus);
    afterThirdTestKiloByte = rus.ru_maxrss;
    printf("Third Test should be grater than 0 : %ld\n", (afterThirdTestKiloByte - afterAddKiloByte));
    CU_ASSERT_TRUE( (afterThirdTestKiloByte - afterAddKiloByte) > 0);

    // now free the memmory and get back to the initial value
    for(i=0; i<loops; ++i){
        free(holder[i]);
    }  
    getrusage(RUSAGE_SELF, &rus);
    afterForuthTestKiloByte = rus.ru_maxrss;
    printf("Forth Test should be reset to 0 : %ld\n", (afterForuthTestKiloByte - afterAddKiloByte));
    CU_ASSERT_TRUE( (afterThirdTestKiloByte - afterAddKiloByte) == 0);

    puts("- ----------------------- -");
}

My output is:

- test Memory Free Check  -
- ----------------------- -
- This test takes a while -

Initial KB Used: 458752
After a char add KB Used: 458752
[...]
First Test should be 0 : 0
Second Test should be 0 (4096 is ok for some reasons): 4096
Third Test should be grater than 0 : 1601536
Forth Test should be reset to 0 : 1601536
- ----------------------- -

I have two questions that i can't explain myself by now: 1. why is the second Test 4096 and not 0? 2. Why is the Forth test no 0?

The fourth test freaks me out. Please take a look and maybe you can explin how to test a free memory call. I assume that the memory manager do not kill the bytes, but reuse it, so the memory will infect rus.ru_maxrss. But how can I test the free?

Thanx a lot, Peter

Answers


Memory allocated with malloc doesn't get returned to the OS, even when free'd. Memory is not returned to the OS until program exit.

getrusage returns the amount of memory in use by your program as measured by the OS.

Combine the above information and you have your answer to both questions.


Need Your Help

How to determine if a language is recursive or recursively enumerable?

recursion computer-science context-free-grammar turing-machines

I have to determine whether a language (for example L={a^n b^m c^s | 0&lt;=n&lt;=m&lt;=s}) is regular, context-free, recursive, recursively enumerable or none of them.

Kendo uI datepicker disable type and selection

kendo-ui

I am trying to disable typing and selecting a date in kendo ui datepicker. Unfortunately the following code only disable typing but still allow the user select the date.