Свободно ли (ptr) где ptr NULL повреждена память?
Теоретически я могу сказать, что
free(ptr);
free(ptr);
это повреждение памяти, так как мы освобождаем память, которая уже была освобождена.
Но что, если
free(ptr);
ptr=NULL;
free(ptr);
Поскольку ОС будет вести себя неопределенным образом, я не могу получить теоретический анализ того, что происходит. Что бы я ни делал, это повреждение памяти или нет?
Допустимо ли освобождение указателя NULL?
11 ответов
7.20.3.2
free
функцияконспект
#include <stdlib.h> void free(void *ptr);
Описание
free
Функция вызывает пространство, на которое указываетptr
быть освобожденным, то есть предоставленным для дальнейшего распределения. Еслиptr
нулевой указатель, никаких действий не происходит.
См. ISO-IEC 9899.
При этом, глядя на различные кодовые базы в дикой природе, вы заметите, что люди иногда делают:
if (ptr)
free(ptr);
Это связано с тем, что некоторые среды выполнения C (я точно помню, что это было на PalmOS) зависали при освобождении NULL
указатель.
Но в настоящее время я считаю, что можно предположить, free(NULL)
это не в соответствии с инструкциями стандарта.
Все совместимые со стандартами версии библиотеки C рассматривают бесплатные (NULL) как неактивные.
Тем не менее, в свое время было несколько версий free, которые могли бы потерпеть крах на free(NULL), поэтому вы можете увидеть, что некоторые методы защитного программирования рекомендуют:
if (ptr != NULL)
free(ptr);
Если ptr равен NULL, никакие операции не выполняются.
говорит документация.
free(ptr);
ptr=NULL;
free(ptr);/*This is perfectly safe */
Вы можете безопасно удалить пустой указатель. В этом случае никакие операции выполняться не будут. Другими словами, free() ничего не делает с указателем NULL.
Рекомендуемое использование:
free(ptr);
ptr = NULL;
Увидеть:
man free
The free() function deallocates the memory allocation pointed to by ptr.
If ptr is a NULL pointer, no operation is performed.
Когда вы установите указатель на NULL
после free()
ты можешь позвонить free()
снова и никакая операция не будет выполнена.
free(NULL)
совершенно законно в C, а также delete (void *)0
а также delete[] (void *)0
законны в C++.
Кстати, освобождение памяти дважды обычно приводит к некоторой ошибке во время выполнения, поэтому она ничего не портит.
free(ptr) - это сохранение в C, если ptr равно NULL, однако большинство людей не знают, что NULL не обязательно должен быть равен 0. У меня есть хороший пример старой школы: на C64, по адресу 0, есть такое IO-порт Если вы написали программу на C, обращающуюся к этому порту, вам понадобится указатель, значение которого равно 0. Тогда отвечающая за ядро библиотека c должна будет различать 0 и NULL.
С уважением
Не повреждение памяти, но поведение зависит от реализации. По стандарту это должен быть юридический код.
Хотя в настоящее время это безопасно, я всегда использую следующий макрос для освобождения указателей:
#define FREE(ptr) \
{ \
if ((ptr) != NULL) \
{ \
free(ptr); \
(ptr) = NULL; \
} \
}
ptr указывает на какую-то область памяти, скажем, 0x100.
Когда вы освобождаете (ptr), в основном вы разрешаете диспетчеру памяти использовать 0x100 для другой деятельности или процесса, и, проще говоря, это освобождение ресурсов.
Когда вы делаете ptr=NULL, вы делаете ptr указателем на новое местоположение (давайте не будем беспокоиться о том, что такое NULL). Делая это, вы потеряли отслеживание данных памяти 0x100. Это то, что утечка памяти.
Поэтому не рекомендуется использовать ptr = NULL для правильного ptr.
Вместо этого вы можете сделать некоторые безопасные проверки с помощью:
if (ptr! = NULL) {free (ptr);}
Когда вы освобождаете (ptr), где ptr уже указывает на NULL, он не выполняет никаких операций. Так что это безопасно.