2014-02-21 29 views
0

我有存储器碎片的问题可以以这种小例子来概括:这是内存碎片吗? (视觉工作室和MinGW)

#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"); 
} 

该程序打印(Win7上编译MSVC(都与调试和releas分配器)和MinGW ):

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

是否有反正我可以避免这种情况?在我真正的应用程序中,我无法避免这种情况,我的程序达到了2GB的内存限制......但我希望能够通过释放某些东西来继续。

为什么碎片在这个小例子中首先发生?当我开始执行“free-s”时,为什么内存块没有压缩,因为它们应该是相邻的。

谢谢!

回答

0

内存碎片是分配不同大小的内存的结果,每个内存具有不同的寿命。这是在空闲内存中创建的空洞,总共足以满足单个分配请求,但每个空洞本身太小。

在你的程序中的情况似乎是揭示了一个错误,你的堆管理代码不能合并相邻的已释放内存。我确实希望有一个由您的分配序列创建的64 KB空洞。

为了避免这个特殊问题,我只需要坚持第一次分配,当我完成它,将它存储在我自己的“自由列表”中就可以这么说。然后下次我需要它时,我会从“自由列表”中取而不是调用malloc()