2

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?

Mehdi Charife
  • 722
  • 1
  • 7
  • 22
Peter Shaw
  • 1,867
  • 1
  • 19
  • 32

1 Answers1

1

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.

orlp
  • 112,504
  • 36
  • 218
  • 315
  • Thanks a lot nightcracker, taht makes sense. but do you know a trick how to tset if a function free'd all allocated space? I have some trouble in a function of a project that i have to write a test for to get it clear and proved. – Peter Shaw Apr 05 '12 at 09:48
  • @PeterShaw: If my answer solved your problem consider marking it as the accepted answer by ticking the checkbox to the left of my answer. – orlp Apr 05 '12 at 09:48
  • 1
    @PeterShaw: generally you use a tool like `valgrind` for tests like this. But if you really want to return the memory to the OS you will have to use the API of your OS to allocate/free memory. AFAIK there is no way to make the C runtime do this for you. – orlp Apr 05 '12 at 09:50
  • It's a answer to all my both questions, but do you know how i test my function that eats more and more ram? I have to be sure taht i fixed it. TIA. – Peter Shaw Apr 05 '12 at 09:50