Отложенное освобождение памяти

Последнее обновление: 08.09.2023

Освобождение памяти, даже будучи выполненым, может быть чревато ошибками. Например, если освободить память раньше, чем нужно, то можно получить "висячий указатель" (dangling pointer). Либо можно по ошибки освободить одну и ту же память дважды, что приведет к неопределенному поведению. Поэтому если программа использует динамическую память для хранения данных, но при этом память выделяется не часто, а сама программа выполняется довольно быстро, то можно переложить на операционную систему обязанность по особождению памяти. И после завершения программы ОС сама освободит всю связанную с программой память.

Стоит отметить, что данное обстоятельно не стоит использовать в качестве оправдания вообще не освобождать память, поскольку диапазон возможных ситуаций, где подобное можно применять, довольно ограничен. Так, если программа часто выделяет память или работает продолжительное время, очевидно, что данный подход не подойдет. Кроме того, программа может эволюционировать, соответственно ситуация может меняться, а подобный подход может быть уже не применим.

Например, возьмем следующую программу:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

// получаем длину файла
int getFileLength(FILE* fp)
{
    fseek(fp, 0, SEEK_END);
    int file_length = ftell(fp);
    return file_length;
}
// считываем файл в buffer
void readFile(FILE* fp, char* buffer, int file_length)
{
    fseek(fp, 0, SEEK_SET);
    int read_elements = fread(buffer, 1, file_length, fp);
    buffer[read_elements] = '\0';   // устанавливаем концевой нулевой байт для строки
}

int main(void)
{
    char* filename = "test.txt"; 
    FILE* fp = fopen(filename, "r");
    // если не удалось открыть файл, останавливаем программу
    assert(fp && "Unable to open file!\n");
    
    int file_length = getFileLength(fp);  // получаем длину файла
    char* text = malloc(file_length);
    if(text)    // если удалось выделять память
    {
        readFile(fp, text, file_length);  // считываем файл
        printf(text);
    }
    fclose(fp);
}

Здесь функция getFileLength получает длину файла, а функция readFile считывает файл в строку. В функции main сначала считывем размер файла и затем используем этот размер для выделения буфера. Если выделение памяти прошло успешно, то считываем в буфер текстовый файл (в данном случае файл test.txt, который, как подразумевается, находится в папке программы).

После считывания файла и вывода считанного текста на консоль буфер явным образом не закрывается. По большому счету в этом нет большого смысла, поскольку после вывода строки фактически идет закрытие файла и конец программы. Соответственно после этого операционная система сама очистит память приложения.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850