2013-09-23 3 views
1

привет я delevop в multicontainner с помощью шаблонов, но я получаю ошибку сегментации из класса ребенок деструктора, вот код:C++ ошибка Сегментация в дочернем классе деструктор

#include <algorithm> 
#include <map> 
#include <iostream> 
class BaseType{ 
public: 
    virtual ~BaseType(){} 
    virtual BaseType * clone() const =0; 
}; 

template<typename T> 
class DataType : public BaseType 
{ 
public: 
    DataType(const T & aValueData = T()):mValue(aValueData) { 
     // new DataType<T>(*this) 
    } 
    ~DataType(){ 

    } 
    BaseType * clone() const 
    { 
     return new DataType<T>(*this); 
    } 

    T mValue; 
}; 

    class MValueData 
    { 
    public: 
     template<typename T> 
     MValueData(T const & aAnyValue = T()):mTypeData(0),isDelete(false) 
     { 
      std::cout<<"Object Address before create object: "<<mTypeData<<std::endl; 
      mTypeData=new DataType<T>(aAnyValue); 
      std::cout<<"Object Address after create object"<<mTypeData<<std::endl; 
     } 
     ~MValueData(){ 
      std::cout<<"Object Address "<<mTypeData<<std::endl; 

      delete mTypeData; 
      mTypeData=0; 


     } 
     MValueData() 
     { 
      mTypeData=0; 
     } 
     template<typename T> 
     MValueData(const MValueData & aCopy) 
     { 

      mTypeData= new DataType<T>(); 
      *mTypeData=aCopy.mTypeData; 
     } 
     template<typename T> 
     const MValueData & operator=(const MValueData & aCopy) 
     { 
      mTypeData= new DataType<T>(); 
      *mTypeData=aCopy.mTypeData; 
      //MValueData(aCopia).swap(*this); 
     } 
     void swap(MValueData& other) { 
      std::swap(this->mTypeData, other.mTypeData); 
     } 

     template <typename T> 
     T& get() 
     { 
       return dynamic_cast<DataType<T>&>(*this->mTypeData).mValue; 
     } 

     bool operator <(const MValueData &rhs) const { 
      return (mTypeData<rhs.mTypeData); 
     } 
     template<typename T> 
     void setValue(T const & anyValue=T()) 
     { 
      mTypeData= new DataType<T>(anyValue); 
     } 
     BaseType *mTypeData; 
    private: 

     bool isDelete; 
    }; 

    int main() 
    { 
     MValueData aAnyType_1(0.22); 
     aAnyType_1.get<double>(); 
     MValueData aAnyType_2(false); 
     std::map<MValueData , MValueData&> mMapa; 
     mMapa.insert(std::pair<MValueData , MValueData&>(aAnyType_1,aAnyType_2)); 
//  mMapa.find(aAnyType_1); 
     return 0; 
    } 

Я использую GDB для детерминированных ошибка, но я не могу видеть, как правильно исправить, то segmentacion стоп, когда я закомментировать эту строку:

~MValueData(){ 
     // if(mTypeData) delete mTypeData; 
     } 

только тогда запустить propperly, но мне кажется, что я творю утечку памяти. Обновлено: std :: map создать копии объекта, в который я вставляю, объект уничтожается дважды, один при выходе из основной функции и другой, когда std :: map уничтожает его самостоятельно, любой намек? THX заранее!

ответ

5

Эта ошибка сегментации может оказаться в деструкторе, но это проблема в вашем конструкторе копирования. Давайте возьмем простой пример, у меня есть класс, который хранит указатель. Затем я копирую это значение указателя, как вы делаете: у меня будет два указателя на одно и то же место в памяти. Теперь я удаляю один из этих объектов, удаляя это значение с помощью указателя. Второй объект будет иметь указатель на недопустимую память, а когда он попытается удалить память, вы получите ошибку сегментации.

Как это исправить:

Ну Есть несколько способов, на самом деле. Во-первых, вам нужно решить, хотите ли вы глубокого копирования указателей или нет. Если вы это сделаете, напишите deep copy памяти, на которую указывает указатель. Если нет, повторите попытку с помощью shared_ptr, чтобы избежать подобных проблем.

+1

@OP Одним из способов избежать таких проблем в первую очередь является использование 'unique_ptr' вместо необработанного указателя. Компилятор немедленно пожаловался бы, и вы могли бы сделать любой выбор pippin (глубокая копия или 'shared_ptr') вместо того, чтобы создавать проблемы времени выполнения, которые намного сложнее отслеживать. – syam

+0

я есть попытаться использовать этот конструктор копирования: шаблон MValueData (Const MValueData & mCopia) { mTypeData = новый DataType (); * mTypeData = mCopia.mTypeData; } ,,, но сегментация остается. У меня нет компилятора c11 для использования unique_ptr –

+0

Вы также исправили операцию присваивания для обработки вещей аналогичным образом? – pippin1289

2

Ваш конструктор копирования поврежден. Вы не клонируете объект, а только указатель. После копирования объекта две копии попытаются удалить один и тот же реальный объект в памяти в деструкторе и это приведет к сбою. Вам нужно выяснить, кто должен владеть объектом и хотите ли вы его клонировать или делиться между различными экземплярами объекта MValueData. Затем действуйте соответствующим образом, чтобы исправить проблему.

1

Неправильный номер copy constructor.

Он копирует только указатель, а не объект.

Два объекта, скопированные с помощью конструктора копии , попытаются удалить один и тот же объект в своем деструкторе.

Смежные вопросы