Zajímavosti z C++: delete na nulový ukazatel

Od Petr Zemek, 2013-11-03

Dnes se podíváme na to, zda je bezpečné volat delete na nulový ukazatel.

Úvod

Občas vídávám následující C++ kód:

if (p) {
    delete p;
}

Nejdříve se podíváme, zda na ukazateli máme nějaká data, a pokud ano, tak dynamicky alokovanou paměť zrušíme. Otázkou ale je, zda je ona kontrola nutná.

Je ta kontrola nutná?

To závisí na tom, o jaký operátor delete se jedná. Pokud se jedná o vlastní přetíženou verzi, pak je odpověď samozřejmě závislá na jeho implementaci. Ve zbytku příspěvku se tedy budu zabývat situací, kdy se jedná o standardní verzi tohoto operátoru.

Pokud se tedy jedná o knihovní verzi operátoru delete, tak ona kontrola je zbytečná. Jestliže je totiž operand od delete nulový ukazatel, tak se nic neprovede. V C++98 normě je to řečeno zde:

5.3.5 §2 "[...] if the value of the operand of delete is the null pointer the operation has no effect."

V C++11 je to napsáno trošičku méně přehledně:

5.3.7 §7 "If the value of the operand of the delete-expression is not a null pointer value, the delete-expression will call a deallocation function (3.7.4.2). Otherwise, it is unspecified whether the deallocation function will be called."
3.7.4.2 §3 "The value of the first argument supplied to a deallocation function may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call has no effect."

První citovaný řádek říká, že v případě nulového ukazatele není specifikováno, zda se zavolá ona dealokační funkce. Pokud se nezavolá, tak delete neprovede nic. Pokud se zavolá, tak druhý citovaný řádek říká, že volání nemá žádný efekt. Onu kontrolu lze tedy bez újmy na bezpečnosti odstranit:

delete p;

Kód pak bude navíc kratší.

Obsah tohoto pole je soukromý a nebude veřejně zobrazen.

Filtrované HTML (využíváno)

  • Povolené HTML značky: <a href hreflang> <em> <strong> <cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <table>
  • Zvýraznění syntaxe kódu lze povolit přes následující značky: <code>, <blockcode>, <bash>, <c>, <cpp>, <haskell>, <html>, <java>, <javascript>, <latex>, <perl>, <php>, <python>, <ruby>, <rust>, <sql>, <text>, <vim>, <xml>, <yaml>.
  • Řádky a odstavce se zalomí automaticky.
  • Webové a e-mailové adresy jsou automaticky převedeny na odkazy.
CAPTCHA
2 + 0 =
Vyřešte tento jednoduchý matematický příklad a vložte výsledek. Např. pro 1+3 vložte 4.
Nějak se mi tady rozmohl spam, takže poprosím o ověření.