Неопределенное поведение при удалении массива символов памяти void * - PullRequest
6 голосов
/ 23 марта 2010

Правда ли, что следующее приводит к неопределенному поведению:

void * something = NULL;
char * buffer = new char[10];

something = buffer;
buffer = NULL;

delete [] something; // undefined??

Сначала мне нужно разыграть something до char *?

Ответы [ 2 ]

5 голосов
/ 23 марта 2010

Да.

Из стандарта (5.3.5 Исключить):

Значение операнда удаления должно быть значение указателя, который результат предыдущего массива new-expression.72) Если нет, то поведение не определено. [Примечание: это означает, что синтаксис выражение-удаление должно соответствовать тип объекта, выделенного новым, не синтаксис нового выражения. ]

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

** Это означает, что объект нельзя удалить с помощью указателя типа void *, поскольку нет объектов типа void.

4 голосов
/ 23 марта 2010

Да, строго, когда вы используете delete[] статический тип указателя, который вы delete[] должны соответствовать типу массива, который вы изначально выделили, или вы получите неопределенное поведение.

Обычно во многих реализациях delete[] вызывается для void*, который на самом деле является массивом типа, у которого нет нетривиальных деструкторов, но это не гарантируется.

delete[] buffer

или

delete[] (char*)something

оба будут действительны.

...