Вопрос
Я часто использую веб-сайт www.cplusplus.com в качестве ссылки при написании кода на Си.
Я читал пример, приведенный на странице для фрейд и у меня возник вопрос.
В качестве примера они публикуют:
/* fread example: read a complete file */
#include <stdio.h>
#include <stdlib.h>
int main () {
FILE * pFile;
long lSize;
char * buffer;
size_t result;
pFile = fopen ( "myfile.bin" , "rb" );
if (pFile==NULL) {fputs ("File error",stderr); exit (1);}
// obtain file size:
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
buffer = (char*) malloc (sizeof(char)*lSize);
if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}
// copy the file into the buffer:
result = fread (buffer,1,lSize,pFile);
if (result != lSize) {fputs ("Reading error",stderr); exit (3);}
/* the whole file is now loaded in the memory buffer. */
// terminate
fclose (pFile);
free (buffer);
return 0;
}
Мне кажется, что если result != LSize, то free (buffer) никогда не будет вызван.Будет ли это утечкой памяти в этом примере?
Я всегда думал, что примеры на их сайте очень высокого качества.Возможно, я неправильно понимаю?
Решение
Это не было бы утечкой памяти в этом примере, поскольку завершение программы (путем вызова exit()
) освобождает всю память, связанную с ним.
Однако это была бы утечка памяти, если бы вы использовали этот фрагмент кода в качестве подпрограммы и вызвали что-то вроде return 1;
на месте exit()
.
Другие советы
Технически, да, это утечка памяти.Но любая память, выделенная процессом, автоматически освобождается при завершении этого процесса, поэтому в этом примере вызовы free (и fclose) на самом деле не требуются.
В более сложной программе это, вероятно, было бы реальной проблемой.Отсутствующий free приведет к утечке памяти, а отсутствующий fclose - к утечке ресурсов.
Операционная система очищает любую несвободную память процессом, когда этот процесс закрывается.По крайней мере, современный операционные системы делают это.
Если программа не завершалась в точке result != LSize, то есть она продолжила выполнение по какому-то другому пути, тогда да - это гарантированная утечка памяти.
Есть два возможных пути.
(1) результат != LSize - в этом случае вызывается exit(0).Это завершает процесс, и операционная система очищает память.
(2) результат == lsize - в этом случае буфер явно освобождается, но сразу после этого вызывается return, так что free - это в основном просто хороший стиль, потому что это также убивает процесс, и операционная система, опять же, очистит память.
Таким образом, в этом простом случае утечки памяти нет.Но, вероятно, хорошей практикой будет просто убедиться, что вы освобождаете всю память, выделенную вами в любом приложении, которое вы пишете.Выработав эту привычку, вы предотвратите множество головных болей в будущем.
Что касается возможной утечки памяти, другие пользователи уже ответили на этот вопрос.Некоторое время назад я опубликовал вариант данного кода, который следует правильно обрабатывайте все возможные условия ошибки: