Доверие - Простой и простой. Правительство не может открыть себя ни для кого изменение, это - код.
, Например: кодер мог сознательно ввести переполнение буфера в ядро Linux. Они знают, что это - местоположение, требуемая полезная нагрузка и моментальный компромисс удара. Это также предлагает отрицание наличия, как это появляется как "просто другая" ошибка переполнения.
Редактирование - Мое опровержение к комментариям: http://www.debian.org/News/2006/20060713
debian ядро поставилось под угрозу через поставивший под угрозу хост. Да, код может быть рассмотрен, но мы все еще определяем новые ошибки даже после 20 лет знания, что переполнение буфера является проблемой.
Обзор не является идеальным вместилищем.
Лично я предпочитаю следующие
template< class T > void SafeDelete( T*& pVal )
{
delete pVal;
pVal = NULL;
}
template< class T > void SafeDeleteArray( T*& pVal )
{
delete[] pVal;
pVal = NULL;
}
. Они компилируются ТОЧНО в один и тот же код в конце.
Может быть какой-то странный способ сломать систему #define, но лично ( И я, наверное, застону от этого;) Я не думаю, что это большая проблема.
Потому что можно удалить указатель NULL (0)
. Нет необходимости проверять, действительно ли указатель равен NULL (0)
или нет. Если вы хотите установить указатель на NULL после удаления, вы можете перегрузить оператор delete
глобально без использования макросов.
Похоже, я ошибался насчет второго пункта:
Если вы хотите установить указатель на NULL, после удаления вы можете перегрузить оператор
delete
глобально
Дело в том, что если вы перегрузите глобальные new
и delete
, у вас может получиться что-то вроде этого:
void* operator new(size_t size)
{
void* ptr = malloc(size);
if(ptr != 0)
{
return ptr;
}
throw std::bad_alloc("Sorry, the allocation didn't go well!");
}
void operator delete(void* p)
{
free(p);
p = 0;
}
Теперь, если вы установите p = 0 ;
в перегруженном удалении
, вы фактически устанавливаете локальный
, но не исходный p
. По сути, мы получаем копию указателя в перегруженном delete
.
Извините, это было в моей голове, я подумал об этом. В любом случае, я бы написал встроенную функцию шаблона, чтобы сделать это, вместо того, чтобы писать ЗЛОЕ МАКРОСЫ :)
удаление нулевого указателя ничего не делает, поэтому перед удалением нет необходимости проверять, является ли указатель нулевым. Обнуление удаленного указателя все еще может потребоваться (но не в каждом случае).
Следует избегать макросов, насколько это возможно, поскольку их сложно отлаживать, поддерживать, вызывать возможные побочные эффекты, они не являются частью пространств имен и т. Д. .
удаление указателя, который не был динамически выделен с помощью new, по-прежнему будет проблемой ...
Ваш макрос не работает по нескольким причинам:
DELETE (getPtr ());
не будет компилироваться, потому что вы не можете установить для вызова функции значение null. Или, если указатель является константным, ваш макрос также не сработает. delete NULL
разрешено стандартом. Наконец, как сказал гримнер, вы пытаетесь решить проблему, которой изначально не должно быть. Почему вы вообще вручную вызываете delete? `Разве вы не используете стандартные библиотечные контейнеры? Умные указатели? Распределение стека? RAII?
Как сказал ранее Страуструп, единственный способ избежать утечек памяти - это избежать вызова delete.
шаблонных
функций
вместо этого NULL
после освобождения имеет тенденцию маскировать ошибки if (ptr! = NULL)
в качестве механизма управления потоком. Лично я считаю
запах кода похож на void foo (int arg)
, заменяемый на void
foo (int arg, bool doAdvancedThings = false)
shared_ptr
и
его родственники должны всегда использоваться для владения, необработанные указатели могут использоваться для
другой доступ if (ptr! = NULL)
вместо if (ptr)
... сравнение указателей - это еще один запах кода Да, вы никогда не должны вызывать удаление напрямую. Используйте shared_ptr, scoped_ptr, unique_ptr или любой другой умный указатель, который есть в вашем проекте.
Потому что на самом деле он не решает многих проблем.
На практике большинство проблем с доступом к висячим указателям возникает из-за того, что другой указатель на тот же объект существует в другом месте программы и является позже используется для доступа к объекту, который был удален.
Обнуление одной из неизвестного количества копий указателя может немного помочь, но обычно это указатель, который либо вот-вот выйдет за пределы области видимости, либо будет указывать на новый объект в любом случае.
С точки зрения дизайна вызов вручную delete
или delete []
должен происходить относительно редко. Использование объектов по значению вместо динамически выделяемых объектов там, где это необходимо; m использование std :: vector
вместо динамически выделяемых массивов и перенос владения объектами, которые должны быть динамически выделены, в соответствующий интеллектуальный указатель (например, auto_ptr
, scoped_ptr
или shared_ptr
) для управления их сроком службы - все это подходы к проектированию, которые делают замену delete
и delete []
на «более безопасный» макрос - подход со сравнительно низкой выгодой.
Потому что DELETE уже определено в winnt.h:
#define DELETE (0x00010000L)
Вместо этого используйте boost :: shared_ptr <>.
http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/shared_ptr.htm
МАКРОС здесь предоставляет некоторые функции, которые вы вероятно ищете.
По моему мнению, выгода не перевешивает затраты.