Shallow copy – copies only the values of the object's fields, including pointers, but does not duplicate dynamically allocated memory. As a result, both objects point to the same memory area. This can lead to errors when modifying data or freeing memory.
Deep copy – creates a full copy of all resources that the object points to, so that each object owns its own copy of the data.
When deep copy is needed:
Example of deep copy implementation:
class ArrayHolder { public: ArrayHolder(size_t size) : sz(size), data(new int[size]) {} ~ArrayHolder() { delete[] data; } // Deep copy constructor ArrayHolder(const ArrayHolder& other) : sz(other.sz), data(new int[other.sz]) { std::copy(other.data, other.data + other.sz, data); } // Deep copy assignment ArrayHolder& operator=(const ArrayHolder& other) { if (this != &other) { delete[] data; sz = other.sz; data = new int[sz]; std::copy(other.data, other.data + sz, data); } return *this; } private: size_t sz; int* data; };
Question: Will the copy constructor work correctly if it simply copies the pointer value?
Answer: No, this will lead to double deletion of memory when both objects are destroyed. Deep copying must be implemented for proper resource management.
Story
In one of the projects, to pass arrays between modules, class objects were used where the default copy constructor copied only the pointer (shallow copy). As a result, after the temporary object went out of scope, the array was destroyed, while the main object was left with a "dangling" pointer, leading to undefined behavior and application crashes.
Story
In a library for working with images, objects containing dynamically allocated buffers were repeatedly copied. Due to the absence of deep copy, after freeing memory in one object, another accessed the freed area. This led to both data corruption and crashes when deleting the object.
Story
When integrating legacy code with modern standards, old classes did not have either the copy constructor or assignment operator implemented. Using these classes with standard library containers led to unexpected failures, as the containers copied objects shallowly.