Phillip Pearson - web + electronics notes

tech notes and web hackery from a new zealander who was vaguely useful on the web back in 2002 (see: python community server, the blogging ecosystem, the new zealand coffee review, 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: []