Phillip Pearson - Second p0st

tech notes and web hackery from the guy that brought you bzero, python community server, the blogging ecosystem, the new zealand coffee review and the internet topic exchange

2003-5-20

C++ default copy constructor considered harmful

An annoyingly common bug in C++ apps: accidental double-freeing due to the default copy constructor memcpy()ing whole objects and duplicating pointers, which then get freed each time the destructor fires.

class A
{
    char* foo;
public:
    A() { foo = new char[100]; }
    ~A() { delete[] foo; }
};

int main()
{
    A a; // A() is called
    A b = a; // object is copied
    
    // function exit:
    // b.~A() is called, deleting b.foo
    // a.~A() is called, deleting a.foo, which fails as a.foo == b.foo
}


If you need to hold a reference to an object, it's better (quicker) to store a pointer:

    A* b = &a;

Now, when b falls out of scope, nothing gets deleted, which is good, because a will delete the object's data fine by itself.

To make sure you don't run into a bug like this, declare a private copy constructor that doesn't do anything. Now any attempt to copy an instance of the object will fail as nobody can get at the copy constructor.

class A
{
    char* foo;
    A(const A& other) {}
public:
    A() { foo = new char[100]; }
    ~A() { delete[] foo; }
};


Visual C++ 7 gives me an error C2248: 'A::A' : cannot access private member declared in class 'A' when I try to copy it after implementing the fake copy constructor.
... more like this: []