【问题标题】:c++ Segmentation fault in destructor child classc ++析构函数子类中的分段错误
【发布时间】:2013-09-24 03:40:15
【问题描述】:

嗨,我正在使用模板开发一个多容器,但是我从子类析构函数中得到了分段错误,这里是代码:

#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;
        }

只有这样它才能正常运行,但似乎我正在创建内存泄漏。 更新:std::map 创建我插入的对象的副本,该对象被销毁两次,一​​次在退出主函数时,另一次在 std::map 自行销毁时, 任何提示? 提前谢谢!

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    此分段错误可能出现在析构函数中,但它是您的复制构造函数中的问题。让我们举一个简单的例子,我有一个存储指针的类。然后我像你一样复制这个指针值:我将有两个指向同一个内存位置的指针。现在我删除这些对象之一,从而删除指针处的值。第二个对象将有一个指向无效内存的指针,当它尝试删除内存时,您会遇到分段错误。

    如何解决这个问题:

    其实有几种方法。首先,您需要决定是否要深度复制指针。如果你这样做了,也写一个指针指向的内存的deep copy。如果没有,我建议使用shared_ptr 来避免这些问题。

    【讨论】:

    • @OP 首先避免此类问题的一种方法是使用unique_ptr 而不是原始指针。编译器会立即抱怨,您可以选择 pippin 建议的任何一种(深拷贝或shared_ptr),而不是遇到更难以跟踪的运行时问题。
    • 我曾尝试使用此复制构造函数:template MValueData(const MValueData & mCopia) { mTypeData= new DataType(); *mTypeData=mCopia.mTypeData; },, 但是分割仍然存在。我没有 c11 编译器来使用 unique_ptr
    • 您是否也修复了分配操作以类似地处理事情?
    【解决方案2】:

    你的复制构造函数坏了。您不是在克隆对象,而只是在克隆指针。一旦一个对象被复制,两个副本将尝试在析构函数中删除内存中相同的真实对象,这将导致崩溃。您需要弄清楚谁应该拥有该对象,以及您是否希望在MValueData 对象的不同实例之间克隆或共享它。然后采取相应措施解决问题。

    【讨论】:

      【解决方案3】:

      您的copy constructor 不正确。

      它只复制指针而不是对象。

      使用复制构造函数复制的两个对象将尝试在其析构函数中删除同一个对象。

      【讨论】:

        猜你喜欢
        • 2015-04-05
        • 1970-01-01
        • 2012-02-05
        • 2016-07-05
        • 1970-01-01
        • 2013-04-30
        • 2012-03-09
        • 1970-01-01
        • 2021-08-15
        相关资源
        最近更新 更多