Как мне освободить память в C? - PullRequest
30 голосов
/ 30 января 2012

Я пишу код, который имеет много одномерных и двухмерных массивов. Я получил «ошибка: не могу выделить регион», и я думаю, что это потому, что выделено слишком много памяти. Я использую функции "malloc" и "free", но я не уверен, что использую их правильно. Может быть, вы знаете, где я мог видеть хорошие примеры по управлению памятью в C?

итак .. Я просто пытаюсь заставить работать один алгоритм, а пока этот код является просто функцией после функции ..

//memory allocation for 1D arrays
buffer = malloc(num_items*sizeof(double));

//memory allocation for 2D arrays
double **cross_norm=(double**)malloc(150 * sizeof(double *));
for(i=0; i<150;i++)
    {
        cross_norm[i]=(double*)malloc(num_items*sizeof(double));
    }

    //code
Window(N, window_buffer);
STFTforBMP(buffer,N,f, window_buffer);
getMagnitude(buffer,f, N, magnitude);
calculateEnergy(flux,magnitude, f);
calculateExpectedEnergy(expected_flux, candidate_beat_period, downbeat_location, f);
calculateCrossCorrelation(cross, flux, expected_values, f);
findLargestCrossCorrelation(&cross_max, cross, f);
normalizeCrossCorrelation(cross_norm, &cross_max, cross, f);
    ...............

Как использовать функцию free?

Ответы [ 2 ]

41 голосов
/ 30 января 2012

Вы должны free() выделить память в точном порядке, обратном тому, как она была выделена с помощью malloc().

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

выделение памяти для 1D-массивов:

    buffer = malloc(num_items*sizeof(double));

освобождение памяти для 1D-массивов:

    free(buffer);

выделение памяти для 2D-массивов:

    double **cross_norm=(double**)malloc(150 * sizeof(double *));
    for(i=0; i<150;i++)
    {
        cross_norm[i]=(double*)malloc(num_items*sizeof(double));
    }

освобождение памяти для 2D-массивов:

    for(i=0; i<150;i++)
    {
        free(cross_norm[i]);
    }

    free(cross_norm);
28 голосов
/ 30 января 2012

На самом деле вы не можете вручную «освободить» память в C, в том смысле, что память освобождается из процесса обратно в ОС ... когда вы вызываете malloc(), базовая среда выполнения libc будет запрашивать у ОС область памяти. В Linux это может быть сделано через относительно «тяжелый» вызов, такой как mmap(). Как только эта область памяти сопоставлена ​​с вашей программой, существует настройка связанного списка, называемая «свободным хранилищем», которая управляет этой выделенной областью памяти. Когда вы вызываете malloc(), он быстро ищет в свободном хранилище свободный блок памяти требуемого размера. Затем он корректирует связанный список, чтобы отразить, что был выделен кусок памяти из первоначально выделенного пула памяти. Когда вы вызываете free(), блок памяти помещается обратно в свободное хранилище как узел связанного списка, который указывает на доступный кусок памяти.

Если вы запрашиваете больше памяти, чем находится в бесплатном хранилище, libc-runtime снова запросит больше памяти у ОС до предела способности ОС выделять память для запущенных процессов. Когда вы освобождаете память, она не возвращается обратно в ОС ... она обычно возвращается обратно в хранилище, где она может быть снова использована другим вызовом malloc(). Таким образом, если вы делаете много вызовов malloc() и free() с запросами с изменяющимся размером памяти, теоретически это может вызвать состояние, называемое «фрагментация памяти», когда в свободном хранилище достаточно места для выделения ваш запрошенный блок памяти, но недостаточно непрерывных места для размера запрашиваемого блока. Таким образом, вызов malloc() завершается неудачно, и вы фактически «не хватает памяти», хотя в свободном хранилище может быть достаточно памяти в виде общего количества байтов.

...