В посте Проблемы с delete[] Александр рассказывает про undefined behavior вот такого кода:
A* a = new B[T];
delete[] a;
Рекомендую.
Updated 11.07.2010: Eugene K. справедливо уточняет
Вообще-то для получения проблем необязательно удалять. Достаточно выполнить какой-нибудь доступ к элементу "массива" a с индексом больше нуля.
A* a = new B[T];
a[1].p = 42; // запишет не туда
То есть проблема собственно в строке выделения "A* a = new B[T];". Если над ней помедитировать, то можно догадаться, что она лишена смысла.
13 коммент.:
Ccылка на блог Раймонда Чена в одном из комментариев [http://blogs.msdn.com/b/oldnewthing/archive/2004/02/03/66660.aspx], где обсуждается схожий вопрос, даже более интересна для изучения чем исходный пост
Как обычно, нормальные ОС + IDE этой проблемой не затронуты: в мире Windows всё работает.
http://easy-coding.blogspot.com/2010/06/delete.html?showComment=1276182441327#c1419027836280113277
Нафик использовать сишные массивы с С++ классами, да ещё с полиморфизмом? При смешивании всегда возникают проблемы.
В обсуждении так и не написали, как исправить код, чтобы избежать сегфола.
2huita:
В обсуждении так и не написали, как исправить код, чтобы избежать сегфола.
Я бы использовала тут вектор, а не массив. jia3ep выше тоже на это намекнул...
А всё потому, что нету отдельных типов "указатель на массив", которые было бы запрещено приводить друг к другу.
Интересно, как с сабжем в ди?
Очевидно же.
какбе, даже в Мейерсе написано, что так делать нехорошо, а афтор - малолетний негодяй. см. "Never treat arrays polymorphically"
Да уж. Хорошо было бы ввести аналог до-диезного атрибута класса sealed (или const, как в Java, например; означает запрет наследования) и запретить подобное выражение для классов без этого атрибута.
Шутка :) Там та-ка-а-я ниточка потянется…
Я бы использовала тут вектор, а не массив. jia3ep выше тоже на это намекнул...
Всё равно тип элемента придётся делать указателем (пусть и "умным"). Так что, что вектор, что массив…
vector<A*> v(T); v[1] = new B();
valarray<A*> x(T); x[1] = new B();
A **a = new (A*)[T]; a[1] = new B();
// ...
FOR_EACH_VECTOR_ITEM( v, item, if (item) { delete item; item = 0; } );
FOR_EACH_VALARRAY_ITEM( x, item, if (item) { delete item; item = 0; } );
FOR_EACH_ARRAY_ITEM( a, item, if (item) { delete item; item = 0; } );
delete[] a;
Здравствуйте Алёна!
Прошу прощения, я может быть один тут дурень такой, но чёт я не пойму в чём тут баг ?
Вот я написал:
class A
{
public:
A(): t(0) {};
virtual ~A(){};
int t;
};
class B: public A
{
public:
virtual ~B(){};
};
void main()
{
A* a = new B[3];
a[1].t = 3;
a[2].t = 5;
delete[] a;
}
всё прекрасно фурычит..
или я где-то допустил ошибку ? )
glad18:
Здравствуйте Алёна!
Приветствую!
Прошу прощения, я может быть один тут дурень такой, но чёт я не пойму в чём тут баг ?
Посмотрите пост, на который я ссылаюсь: http://easy-coding.blogspot.com/2010/06/delete.html
Там подробно объяснено что именно не так, а также почему в VC++ проблемы не видны.
Отправить комментарий