3

Почему мне подсвечиваются подсказки для массивов где я делаю проверку на nullptr перед вызовом delete[], получаю подсказку о том что вызов delete[] для nullptr не производит никаких эффектов?

Это правда, или это лишь поддержка с какого-то стандарта, или подсказка о том что я в коде нигде не заполняю массив, и его можно спокойно удалять даже с значением nullptr?

Harry
  • 221,325

2 Answers2

12

Стандарт утверждает, что оператору delete (delete[]) можно смело передавать nullptr - просто в этом случае оператор не будет делать ничего (см. п. 5.3.5.2 стандарта).

...значение операнда delete может представлять собой нулевое указательное значение, либо указатель на объект-немассив, созданный посредством некоторого предыдущего new-выражения, либо быть указателем на подобъект (1.8) базового класса объекта-немассива (глава 10). В противном случае поведение программы не определено.

Примерно то же говорится и для оператора delete[]:

...значение операнда операции delete может быть нулевым указательным значением, либо указателем, полученным в результате некоторой предыдущей операции new-выражение для массива.

Harry
  • 221,325
  • Бывают ли исключительные случаи в таких ситуациях? –  Jul 16 '18 at 19:55
  • Вы имеете в виду генерацию исключений? Нет. – Harry Jul 16 '18 at 19:56
  • Да, генерацию исключений –  Jul 16 '18 at 19:58
  • 3
    По-хорошему, delete, как и деструкторы, не должны генерировать исключения. В случае delete стандарт гарантирует, что если деструктор не генерирует исключения, то и оператор его генерировать не будет. – Harry Jul 16 '18 at 20:01
2

Ну, во-первых, операторы delete/delete [] в принципе невозможно вызвать ни с каким nullptr. nullptr имеет тип std::nullptr_t и использовать значение этого типа в качестве операнда этих операторов не получится.

Операндом delete/delete [] должен являться либо указатель на объектный тип, либо класс, приводимый к такому указателю. Если указатель является null-указателем, то delete/delete [] просто ничего не делает. Null-указатель и nullptr - это совершенно разные вещи.

Во-вторых, испокон веков в С и С++ (и далеко за их пределами) было принято придерживаться негласного соглашения о том, что средства освобождения ресурсов ничего не делают в ответ на нулевой хендл ресурса. Точно так же, как функция free() ничего не делает в ответ на null-указатель, операторы delete/delete[] ничего не делают в ответ на null-указатель. Этого негласного правила придерживаются во многих API. (fclose с этой точки зрения является неприятным исключением).

  • В некоторых реализациях (насколько помню, в HP-UX так когда-то было) free(0) приводила к segfault – avp Jul 16 '18 at 23:12
  • @avp: Ну это уже частные баги конкретных реализаций... – AnT stands with Russia Jul 16 '18 at 23:14
  • @AnT Вроде как это - безопасность free(NULL) - появилось в каких-то более новых стандартах, а изначально этого не было? – Harry Jul 17 '18 at 07:36