Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Вектор и деструктор


Автор: B3cK 30.5.2006, 16:03
Код

class A{
char *p1;
char *p2;
....
//bla bla bla
public:
A(char* a, char* b)
{
p1=new char[strlen(a)+1];
strcpy (p1,a); 
p2=new char[strlen(b)+1];
strcpy (p2,b);
}
~A(){delete[]p1;
         delete[]p2;
        }
....
//bla bla bla
};       

При добавлении нового объекта данного класса в вектор вылетает ошибка "Debug Assertion Failed!".
Компилятор VC6++ ошибок не выводит. Если деструктор закоментировать, то все отлично работает.
Как можно объяснить такое поведение деструктора при добавлении объекта в вектор?

 

Автор: maxim1000 30.5.2006, 16:12
при копировании такого объекта создаётся новый объект с такими же указателями (ну и при присваивании - соответственно)
когда один из них удаляется, указатели становятся некорректными
когда удаляется второй объект, получается ошибка... 

Автор: B3cK 30.5.2006, 16:39
Подожди, какое копирование, присваивание.
Я через функцию push_back() помещаю в конец вектора
новый полностью инициализированный объект.
 

Автор: maxim1000 30.5.2006, 17:15
Цитата(B3cK @  30.5.2006,  15:39 Найти цитируемый пост)
Я через функцию push_back() помещаю в конец вектора
новый полностью инициализированный объект

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

Автор: MAKCim 30.5.2006, 17:15
Цитата

Подожди, какое копирование, присваивание.
Я через функцию push_back() помещаю в конец вектора
новый полностью инициализированный объект.

создается копия объекта, а т к у тебя не определен копирующий конструктор и ты работаешь с чистыми указателями, возможны проблемы
напиши
Код

class A
{
...
public:
    A(const A& obj)
        : p1(new char [strlen(obj.p1)+1]), p2(new char [strlen(obj.p2)+1])
    {
        strcpy(p1,obj.p1);
        strcpy(p2,obj.p2)
    }
};
 

Автор: B3cK 30.5.2006, 17:28
Спасиб, теперь конфликт понятен.
Вопрос закрыт. 

Автор: Earnest 30.5.2006, 17:37
Оператор присваивания тоже нужен. Самый простой способ проверить - декларировать в private-секции оператор присваивания и выслушать от компилятора массу приятных слов.

Вообще лучше всегда явно определять, копируемый класс ты пишешь или нет. Т.е. если в классе используются некопируемые сущности (указатели или какие-нибудь неразделяемые дескритпоры ресурсов), нужно либо явно определять операторы копирования, либо относить их в private-секцию. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)