Удаление псевдонима - PullRequest
       10

Удаление псевдонима

3 голосов
/ 23 сентября 2011

Делаем это:

 union{
     int * integer;
     char * character;
 } u;
 u.integer = new int;
 delete u.character;

 u.integer = new int[5];
 delete [] u.character;

Я предполагаю, что это не сработает, если у любого из этих типов есть нетривиальные деструкторы, но это нормально?

Ответы [ 4 ]

8 голосов
/ 23 сентября 2011

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

1 голос
/ 23 сентября 2011

Я хочу сказать, что это где-то между реализацией определенной и неопределенной.

5.3.5 / 2: «В первом варианте (удаление объекта) значение операндом удаления может быть ... указатель на объект не массив, созданный предыдущим выражением new ....

Значение указателя не изменяется при использовании так, как вы это сделали, поэтому это должно работать как положено, если sizeof(char*) == sizeof(int*) Результат этого конкретного сравнения определяется реализацией, и если предположение ложно, то поведение не определено.

Так что это действительно не особо безопасно.

1 голос
/ 23 сентября 2011

Нет, это неопределенное поведение независимо от того, есть ли у элемента тривиальный деструктор.Если деструктор тривиален, он может казаться «работающим», когда фактически происходит утечка памяти и т. Д.

0 голосов
/ 24 сентября 2011

Легко видеть, что это опасная ошибка.Эти два типа могут иметь совершенно разные и несовместимые способы выделения и освобождения памяти.Это включает заполнение, сборку мусора, бухгалтерию, манипулирование памятью для каждого класса и т. Д. Просто не делайте этого.

...