2014-02-21 62 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()