A "pointer being freed was not allocated problem" when testing copy constructor

Viewed 34

In my work I need to use the base class pointer to realize polymorphism and I write a "list" class to store the base class pointers using vector. Some methods are included just for convenience.

The base class is as follows:

class Base
{
private:
    std::string mTypeName;          // To make type conversion from base class pointer to
                                    // detivation pointer
public:
    /// a base class member variable
    std::vector<double> mValues;   // It is supposed to be a vector with 3 double elements
    
    /// Constructor
    Base()
    {
        mValues.resize(3);
    }
    
    /// To set mTypeName
    void setTypeName(std::string name)
    {
        mTypeName = name;
    }
    
    /// To get mTypeName
    std::string getTypeName()
    {
        return mTypeName;
    }
};

The std::string mTypeName member is for type descrimination. The derived classes A and B are as follows:

class DerivationA : public Base
{
private:
    
public:
    /// a Derivation A member variable
    double mA;
    
    /// Constructor
    DerivationA()
    {
        for(int idx = 0; idx < 3; idx++)
        {
            mValues[idx] = idx;
        }
        mA = 1.0;
        setTypeName("DerivationA"); // Set the mTypeName variable to make type conversion
    }
};

class DerivationB : public Base
{
private:
    
public:
    /// a Derivation B member variable
    unsigned long mB;
    
    /// Constructor
    DerivationB()
    {
        for(int idx = 0; idx < 3; idx++)
        {
            mValues[idx] = idx + 3;
        }
        mB = 2;
        setTypeName("DerivationB"); // Set the mTypeName variable to make type conversion
    }
};

And the list to store all the elements is as follows

class List
{
private:
    std::vector<Base*> mList; // Use base class pointer to realize polymorphism
    unsigned long mNumberOfElements; // number of elements in the list
public:
    /// Destructor
    ~List()
    {
        for(int idx = 0; idx < mNumberOfElements; idx++)
        {
            std::string typeName = mList[idx] -> getTypeName();
            if(typeName == "DerivationA")
            {
                delete (DerivationA*)mList[idx];
            }
            else if(typeName == "DerivationB")
            {
                delete (DerivationB*)mList[idx];
            }
            else
            {
                std::cout << "WARNING: Invalid element type name: " << typeName << std::endl;
                delete mList[idx];
            }
        }
        mList.resize(0);
    }
    
    /// Constructor
    List()
    {
        mList.resize(0);
        mNumberOfElements = 0;
    }
    
    /// Copy constructor
    List(const List &obj)
    {
        mNumberOfElements = obj.mNumberOfElements;
        mList.resize(0);
        for(int idx = 0; idx < mNumberOfElements; idx++)
        {
            std::string typeName = obj.mList[idx] -> getTypeName();
            if(typeName == "DerivationA")
            {
                DerivationA* ptr = new DerivationA();
                *ptr = *((DerivationA*)obj.mList[idx]);
                mList.push_back(ptr);
            }
            else if(typeName == "DerivationB")
            {
                DerivationB* ptr = new DerivationB();
                *ptr = *((DerivationB*)obj.mList[idx]);
                mList.push_back(ptr);
            }
            else
            {
                std::cout << "WARNING: Invalid element type name: " << typeName << std::endl;
                mNumberOfElements = mNumberOfElements - 1;
            }
        }
    }
    
    /// add element method
    void add(Base* ptr)
    {
        mNumberOfElements = mNumberOfElements + 1;
        mList.push_back(ptr);
    }
    
    /// get mList method
    std::vector<Base*> getList()
    {
        return mList;
    }
    
    /// get number of element method
    unsigned long getElemNumber()
    {
        return mNumberOfElements;
    }
};

And finally I can make a final structure class FinalStructure:

class FinalStructure
{
private:
    
public:
    /// Constructor
    FinalStructure()
    {
        mValues.resize(3);
        mElementList = List();
    }
    
    /// Copy constructor
    FinalStructure(const FinalStructure &obj)
    {
        mValues.resize(3);
        // copy values
        for(int idx = 0; idx < 3; idx++)
        {
            mValues[idx] = obj.mValues[idx];
        }
        
        // copy element list
        mElementList = List(obj.mElementList);
    }
    
    std::vector<double> mValues;
    List mElementList;
};

I use the following function to test the copy constructor of the FinalStructure:

void test()
{
    FinalStructure structure1 = FinalStructure();
    
    Base* elemPtr1 = new DerivationA();
    DerivationA* ptr1 = (DerivationA*)elemPtr1;
    ptr1 -> mA = 3.3;
    
    Base* elemPtr2 = new DerivationB();
    DerivationB* ptr2 = (DerivationB*)elemPtr2;
    ptr2 -> mB = 4;
    
    structure1.mElementList.add(elemPtr1);
    structure1.mElementList.add(elemPtr2);
    
    FinalStructure structure2 = FinalStructure(structure1);
}

It seems that the error occurs when this test function ends, and the copy constructor of FinalStructure does not function correctly either.

The ERROR comes to me in this way:malloc: *** error for object 0x10077de80: pointer being freed was not allocated

I am wondering what is wrong in my code.

0 Answers
Related