Как освободить память в C?

Я пишу код, который содержит много 1 и 2 мерных массивов. Я получил "ошибку: не могу выделить регион", и я думаю, потому что слишком много памяти выделено. Я использую функции "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 функцию?

Ответ 1

Вы должны 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);

Ответ 2

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

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