2013-10-03 6 views
1

У меня возникли трудности с сбоем, используя auto_ptr. Я знаю, что вы не можете хранить auto_ptr в контейнерах STL. Но как насчет сохранения значений указателя, удерживаемых auto_ptr внутри вектора? Если auto_ptr удаляет сохраненный объект, на который они указывают, последующее уничтожение вектора, который хранит эти внутренние указатели, приводит к сбою моей программы в методе Tidy_ векторов.Сохранение указателей, принадлежащих auto_ptr's, в векторе, вызывающем сбой

ClassA { 
public: 
    ClassA() { 
     auto_pointer_1_.reset(new ClassP()); 
     auto_pointer_2_.reset(new ClassP()); 
     auto_pointer_3_.reset(new ClassP()); 
    }; 

    std::auto_ptr<ClassP> auto_pointer_1_; 
    std::auto_ptr<ClassP> auto_pointer_2_; 
    std::auto_ptr<ClassP> auto_pointer_3_; 

}; 

ClassB { 
public: 
    ClassB(ClassA& a_class_a_) { 
     vector_of_pointers_.push_back(a_class_a_.auto_pointer_1_.get()); 
     vector_of_pointers_.push_back(a_class_a_.auto_pointer_2_.get()); 
     vector_of_pointers_.push_back(a_class_a_.auto_pointer_3_.get()); 
    }; 

    std::vector<ClassP*> vector_of_pointers_; 
}; 

void main(void) { 

    ClassA* class_a_variable_ = new ClassA(); 

    ClassB* class_b_variable_ = new ClassB(*class_a_variable_); 

    delete class_a_variable_; 
    delete class_b_variable_; <--- CRASH in std::vector Tidy_ method 
} 

Может ли кто-нибудь объяснить мне, почему произошел сбой? Когда auto_ptr удаляет свой сохраненный указатель, связанный с ним указатель в векторе больше не указывает на что-либо, но почему это может помешать правильному разрушению вектора?

Благодаря

+1

http://www.gotw.ca/publications/using_auto_ptr_effectively.htm –

+0

Спасибо, но не отвечает на мой вопрос. – AdamDH

+0

Что делает 'ClassP'? – jxh

ответ

0

Как показано там нет никаких проблем с программой, когда заглушка ClassP добавляется, что ничего не делает (и class добавляется при необходимости, и main() изменены, чтобы вернуться int). Поведение, которое вы наблюдаете, может быть связано с повреждением памяти.

Если какое-либо или все ClassA, ClassB или ClassP фактически имеют нетривиальные деструкторы, вполне возможно, что по крайней мере один из их реализаций деструкторов есть ошибка, которая вызывает неопределенное поведение. Вы должны сосредоточить свое внимание на этом.

Поймите, что std::auto_ptr устарел, и вместо этого вы должны использовать std::unique_ptr, как отметил Бен Фойгт.

+0

Я считаю, что вы правы. Это упрощенный пример более масштабной реализации. Спасибо за ваши усилия и помощь. Я сосредоточу свое внимание на том, что делает ClassP при разрушении. – AdamDH

+0

Я понимаю, что auto_ptr устарел и предпочел бы использовать unique_ptr (я действительно начал с unique_ptr), но понял, что мне приходится поддерживать старые компиляторы, которые не включают unique_ptr или tr1. И использование boost также не работает. – AdamDH

+0

Будущая версия C++ может полностью удалить «auto_ptr», поэтому вы можете использовать «typedef» и «# ifdef», которые выбирают, какой смарт-указатель вы используете. – jxh