Question

I have a problem with memory fragmentation which can be summarized in this small example:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
   void *p[8000];int i,j;
   p[0]=malloc(0x7F000);
    if (p[0]==NULL) 
        printf("Alloc after failed!\n");
    else 
        free(p[0]); 

   for (i=0;i<8000; i++) {
       p[i]=malloc(0x40000);
       if (p[i]==NULL){
          printf("alloc failed for i=%d\n",i);
          break;
       }
    }
    for(j=0;j<i;j++) {
        free(p[j]);
    }
    /*Alloc 1 will fail, Alloc 2 *might* fail, AlloC3 succeeds*/
    p[0]=malloc(0x7F000);
    if (p[0]==NULL) 
        printf("Alloc1 after failed!\n");
    else {printf("alloc1 success\n");free(p[0]);}

    p[0]=malloc(0x40000);
    if (p[0]==NULL) 
        printf("Alloc2 after failed!\n");
    else {printf("alloc2 success\n");free(p[0]);}

    p[0]=malloc(0x10000);
    if (p[0]==NULL) 
    printf("Alloc3 after failed!\n");
    else {printf("alloc3 success\n");free(p[0]);}
   printf("end");
}

The program prints (compiled with MSVC (both with debug and releas allocator) and MinGW on Win7):

alloc failed for i=7896
Alloc1 after failed!
alloc2 success
alloc3 success
end

Is there anyway I can avoid this? In my real application I can't avoid the scenario, my program reaches the 2GB memory limit... but I want to be able to continue by free-ing something.

Why is the fragmentation happening here in this small example in the first place? When I start to do the "free-s" why aren't the memory blocks compacted, as they should be adjacent.

Thanks!

No correct solution

OTHER TIPS

Memory fragmentation is the consequence of allocating memory of varying sizes, each with varying lifespans. This is what creates holes in the free memory that in total are sufficient to satisfy a single allocation request, but each hole is too small by itself.

The situation in your program seems to be revealing a bug your heap management code that is not coalescing adjacent freed memory. I do expect there is a single 64 KB hole created by your allocation sequence.

To avoid this particular problem, I would simply hold on to the first allocation when I am done with it, storing it in my own "free list" so to speak. Then next time I need it, I take it from the "free list" rather than calling malloc().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top