ProgrammingC++ Developer

What is a copy constructor and an assignment operator? How to avoid errors when copying objects with dynamic memory?

Pass interviews with Hintsage AI assistant

Answer

Copy constructor and copy assignment operator are necessary for working with objects that own resources (e.g., dynamic memory). By default, the compiler will generate a field-to-field copy, which is unsafe for raw pointers:

class Buffer { public: Buffer(size_t size) { data = new int[size]; this->size = size; } ~Buffer() { delete[] data; } // Correct implementation of copy constructor Buffer(const Buffer& other) : size(other.size) { data = new int[size]; std::copy(other.data, other.data + size, data); } // Correct copy assignment operator Buffer& operator=(const Buffer& other) { if (this != &other) { delete[] data; size = other.size; data = new int[size]; std::copy(other.data, other.data + size, data); } return *this; } private: int* data; size_t size; };

Otherwise, when copying two objects, one will free the memory while the other will be left with a dangling pointer (double free or use after free).

Trick question

What will happen if only the copy constructor is explicitly declared but not the assignment operator? When is it needed, and when is it not?

Answer: If only the copy constructor is declared but the assignment operator is not declared, the compiler will generate a default assignment operator (bitwise copy), which is dangerous if the object contains dynamic resources, meaning it will free the same pointer twice.

In the case of memory management, both: the copy constructor and the assignment operator must be implemented to avoid copy/memory leak errors.

Examples of real errors due to ignorance of the topic subtleties


Story

In a media server, when copying a buffer object, they used the copy constructor but forgot about the assignment operator. When one buffer was assigned to another, it resulted in double memory freeing upon destruction of the objects. The error manifested during stress tests.


Story

In a transportation logistics project, the default assignment operator copied a structure with a pointer to an array of coordinates. After one object was deleted, the second one accessed the freed memory, causing segmentation faults.


Story

In one of the projects with graphical resources, they forgot to implement the copy constructor when passing objects between threads. Passing by value led to shallow copy, and after modification of the object in another thread, data corruption and program crashes occurred.