Вызов delete или delete [] по NULL-указателю

Безопасно ли всегда опускать проверку указателя NULL перед вызовом Удалить или Удалить[], особенно при написании межплатформенных разделов кода?

Я помню, что несколько лет назад (три или четыре) тот же код, который я написал, работал в MS Windows (скомпилирован с помощью инструментария MSVCv12), но версия, скомпилированная для Linux с g ++ (к сожалению, я не помню версию g ++), выдавала ссылку на указатель NULL. Я нашел информацию, что в то время это, вероятно, была ошибка компилятора.

Я нашел этот SO поток, но, прочитав его, я все еще не совсем уверен, безопасно ли это, и если да, то из какой версии стандарта C++?

что значит «выбросить ссылку на NULL-указатель»?

463035818_is_not_a_number 11.05.2018 12:13

"Я нашел информацию, что в то время это, вероятно, была ошибка компилятора." Как компилятор может проверить, что удаляемый указатель является nullptr, и выдать для него ошибку?

Algirdas Preidžius 11.05.2018 12:17

@ AlgirdasPreidžius Уверен, что они имели в виду "ошибку компилятора".

Baum mit Augen 11.05.2018 12:17

Правильно, я имел в виду «ошибку компилятора», а не «ошибку компилятора». Прошу прощения за свою ошибку.

elklepo 11.05.2018 12:19

используйте умный указатель или вектор, и вам больше не нужно беспокоиться об удалении слова

UKMonkey 11.05.2018 12:29

Я вспоминаю пару ОЧЕНЬ старых компиляторов C++ (примерно с 1992 года), в которых delete (any_type *)NULL или delete [] (any_type *)NULL вызывали ошибку времени выполнения. Но оба этих компилятора (или их библиотеки) были исправлены в следующем выпуске, предположительно из-за отчетов об ошибках. Я не знаю ни одного компилятора более позднего, чем 1995 год, который неправильно работает с delete NULL, т.е. не имеет никакого эффекта. В современных компиляторах сбой при любом использовании оператора delete, включая delete NULL, обычно является признаком ДРУГОГО предыдущего кода в программе, демонстрирующего неопределенное поведение.

Peter 11.05.2018 12:51
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
2 729
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Да, стандарт, начиная с C++ 98, гарантирует, что delete или delete[] на нулевой указатель не действуют.

С ++ 98 §5.3.5 / 2

In either alternative, if the value of the operand of delete is the null pointer the operation has no effect.

Так было и до появления первого стандарта, когда язык был определен в Аннотированном справочном руководстве.


Касательно

version compiled for Linux with g++ (unfortunately, I do not remember the g++ version) was throwing NULL pointer reference

Это невозможно обсуждать без конкретного и, желательно, полного примера, воспроизводящего поведение. Это не имело ничего общего с удалением нулевого указателя.

есть одна небольшая деталь о C++ 11 и более поздних версиях: не указано, вызывается ли функция освобождения или нет, если указатель имеет значение null, поэтому было бы небезопасно, если функция освобождения повторно реализована пользователем таким образом, чтобы это могло вызвать ошибку или UB если указатель равен nullptr. Но это случай, когда нужно изготовить грабли и после этого наступить на них.

Swift - Friday Pie 11.05.2018 13:12

@Swift - operator delete и operator delete[] необходимы для разумной обработки нулевых указателей. «Требуется: [аргумент указателя] должен быть нулевым указателем или его значение должно быть значением, возвращенным более ранним вызовом [оператора new]». [new.delete.single], повторяется в [new.delete.array]. Если вы замените оператор delete, вы заметите, что ваша версия может быть вызвана с нулевым указателем.

Pete Becker 11.05.2018 14:32

@PeteBecker Я знаю это, но некоторые нет. Были вопросы об этом на SO. Я просто отметил это как источник небезопасного поведения в дополнение к довольно хорошему и одобренному ответу. Дело в том, что когда мы пишем delete, это выражение delete, которое будет полагаться на оператор delete, предоставленный пользователем, если он есть. Как и в случае с компилятором нового выражения, он действует как посредник. Некоторые воображают, что компилятор пытается это исправить, а ISO оставляет это неопределенным.

Swift - Friday Pie 11.05.2018 17:11

Другие вопросы по теме