c++heap-memorydynamic-memory-allocationstack-memoryshallow-copy

A class with a pointer pointing to another class as a member variable and pushing it into vector


using namespace std;
class B {
public:
    B() :m_i(0), m_Name("") {};
    B(const int num, const string& name) :m_i(num), m_Name(name) {};
    void showInfo() {
        cout << this->m_i << ", " << this->m_Name << endl;
    }
    friend class A;
private:
    int m_i;
    string m_Name;
};

class A {
public:
    A(const int num, const string& name) :m_i(num), m_Name(name), ptr(nullptr) {};
    A(const A& orig) {
        m_i = orig.m_i;
        m_Name = orig.m_Name;
        ptr = new B;
        ptr = orig.ptr;
    }
    void showInfo() {
        cout << this->m_i << " " << this->m_Name << endl;
        if (ptr) {
            cout << ptr->m_i << " " << ptr->m_Name << endl;
        }
    }
    ~A() {
        delete ptr;
    }
    friend class C;
private:
    int m_i;
    string m_Name;
    B* ptr;
};
class C {   
public:
    void function() {
        A instanceA1(10, "Hello");
        A instanceA2(11, "Hello");
        A instanceA3(12, "Hello");
        {//another scope
            B* instanceB1 = new B(10, "Bye");
            instanceA1.ptr = instanceB1;
            B* instanceB2 = new B(11, "Bye");
            instanceA2.ptr = instanceB2;
            B* instanceB3 = new B(12, "Bye");
            instanceA3.ptr = instanceB3;
        }
        DB.push_back(instanceA1);
        DB.push_back(instanceA2);
        DB.push_back(instanceA3);

        DB[0].showInfo();
        DB[1].showInfo();
        DB[2].showInfo();
    };
private:
    vector<A> DB;
};

int main(void) {
    C console;
    console.function();
}

I had to build a copy constructor of A since there is a pointer as a member variable and as far as I know push_back() only does a 'shallow copy' of an object. However, although my desired output is 10 Hello 10 Bye 11 Hello 11 Bye 12 Hello 12 Bye it prints nothing. And if I delete delete ptr; in A's destructor, it prints what I wanted but I'm pretty sure there is a memory leak. What did I do wrong here?


Solution

  • Here's your copy constructor:

    A(const A& orig) {
        m_i = orig.m_i;
        m_Name = orig.m_Name;
        ptr = new B;
        ptr = orig.ptr;
    }
    

    You assign ptr to a new B but then you turn around and trash it so it points to the original B. I don't think that's what you want. How about this:

        ptr = new B(*orig.ptr);
    

    Does that help?