2014-02-21 3 views
0

У меня есть проблема с фрагментацией памяти, которую можно резюмировать в этом небольшом примере:Является ли эта фрагментация памяти? (Visual Studio и 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"); 
} 

программа печатает (скомпилированный с MSVC (оба с отладкой и RELEAS распределителем) и MinGW на Win7):

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

Есть ли способ избежать этого? В моем реальном приложении я не могу избежать сценария, моя программа достигает предела памяти 2 ГБ ... но я хочу, чтобы иметь возможность продолжать, освобождая что-то.

Почему фрагментация происходит здесь в этом маленьком примере в первую очередь? Когда я начинаю делать «свободные», почему не блокируются блоки памяти, поскольку они должны быть смежными.

Спасибо!

ответ

0

Фрагментация памяти является следствием распределения памяти разных размеров, каждая из которых имеет различную продолжительность жизни. Это то, что создает дыры в свободной памяти, которые в целом достаточны для удовлетворения одного запроса на выделение, но каждое отверстие слишком мало по себе.

Ситуация в вашей программе, по-видимому, выявляет ошибку вашего кода управления кучей, которая не объединяет смежную свободную память. Я ожидаю, что в вашей последовательности выделения будет единственное отверстие размером 64 КБ.

Чтобы избежать этой конкретной проблемы, я бы просто держался за первое выделение, когда я закончил с этим, сохраняя его в моем собственном «свободном списке», так сказать. Тогда в следующий раз мне это нужно, я беру его из «бесплатного списка», а не звоню malloc().