ProgrammingC++ Developer

What happens when an object of a class is passed by value to a function, and what pitfalls should be considered when implementing a copy constructor?

Pass interviews with Hintsage AI assistant

Answer

When an object is passed by value to a function in C++, a copy of the object is created using the copy constructor. If a user-defined copy constructor is defined in the class, it is called to initialize the temporary argument object of the function. If not defined, the default compiler-generated constructor is used, which performs a bitwise copy (shallow copy).

Pitfalls:

  • If the class manages resources (e.g., has raw pointers), the default generated copy constructor will lead to double free errors and memory leaks.
  • It is necessary to ensure that the copy constructor correctly copies the resources (usually deep copy).

Example:

class StringWrapper { char* data; public: StringWrapper(const char* str) { data = new char[strlen(str) + 1]; strcpy(data, str); } // Error: shallow copy StringWrapper(const StringWrapper& other) : data(other.data) {} ~StringWrapper() { delete [] data; } }; void foo(StringWrapper s) { // ... } int main() { StringWrapper s1("hello"); foo(s1); // UB!!! return 0; }

Trick Question

"What will happen if the copy constructor is defined in a class with a pointer like this: MyClass(const MyClass &other) : data(other.data) {}? What consequences does this cause?"

Correct answer: Such a copy constructor will create an object with a pointer to the same memory area as the copied one. When both objects are destroyed, the memory will be freed twice (double free), which leads to undefined behavior. Deep copy should be implemented:

MyClass(const MyClass &other) { data = new int(*other.data); }

Examples of real errors due to lack of knowledge on the topic


Story

In a large server project, containers of objects with a "raw" array inside and a standard copy constructor (shallow copy) were used. When passing objects by value, double free occurred and application crashes were caught only in production.


Story

In an old C++ library for working with images, the copy constructor did not copy the graphics buffer, which led to changing one copy of the image when changing another and unexpected bugs in the interface.


Story

When returning an object by value from a function in one of the internal password storage systems, the data was cleared when the temporary object was destroyed (shallow copy), resulting in the actual object holding a null pointer, and the leak was discovered accidentally during a security audit.