it-swarm.com.ru

Должен ли я освободить память перед выходом?

Должен ли я освободить всю свою неправильно распределенную память при выходе из программы из-за ошибки?

something = (char**) malloc (x * sizeof(char*));
for (i = 0; i < x; i++)
    something[i] = (char*) malloc (y + 1);

...

if (anything == NULL) {
   printf("Your input is wrong!");
   // should I free memory of every mallocated entity now?
   exit(1);
} 
else {
   // work with mallocated entities
   ...
   free(something); // it must be here
   system("pause);
}
16
Lucfia

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

Если в ОС, которая явно освобождает память, у вас все еще есть проблема с другими ресурсами. Когда ваше приложение начинает расти и загружать сторонние библиотеки, вы можете получить утечку ресурсов. Представьте, что я написал библиотеку, которая просит, чтобы вы вызывали close на обработчике. Этот обработчик поддерживается временными файлами, которые не удаляются, пока вы не вызовете close. Или я отключил процессы, которые работают в фоновом режиме, которыми я управляю, используя сигналы или какой-то другой ресурс, о котором вы не знаете.

4
Harry

Это на самом деле очень сложный, невесомый вопрос.

Pro (в пользу освобождения всего перед выходом):

  • нет ошибок или утечек памяти позже, если код переставлен 
  • нет ложных срабатываний от Valgrind или проверки утечки памяти
  • нет утечек памяти, если вы работаете под ошибочной ОС, или вообще нет ОС

Con (просто выйдите, не беспокойтесь о том, чтобы освободить все):

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

В конце концов, вам придется решить, какие из этих плюсов и минусов важнее всего для вас. Разные программисты в разных проектах при разных обстоятельствах придут к разным выводам; здесь нет единого ответа на все вопросы.

См. Также вопрос 7.24 в списке C FAQ .

12
Steve Summit

Вам не нужно освобождать память до завершения программы. Любое завершение программы приводит к автоматическому освобождению всей памяти.

8
fuz

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

Но настоящая причина, по которой вы всегда должны делать это, заключается в том, что освобождение часто выявляет неактивные ошибки времени выполнения в вашем приложении. 

Если у вас есть ошибка где-то, которая вызывает повреждение памяти или изменяет адреса указателя, эта ошибка может оставаться молчаливой и бездействующей. До тех пор, пока вы не измените что-либо, совершенно не связанное с ошибкой, и, следовательно, не будете перемешивать структуру памяти. Затем внезапно происходит сбой, и вы не будете знать, почему, потому что ошибка даже не находится в коде, который вы только что добавили.

Освобождая память, вы провоцируете таких ошибок на поверхность. Потому что, если что-то не так с кучей или указателями, указывающими на кучу, то вы часто будете получать сбой в точке, где вы вызываете free(). Это означает, что у вас есть серьезная ошибка где-то, что вы должны найти перед отправкой программы.

5
Lundin

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

0
Iurii