C++ object as return value: copy or reference?

c++, memory, object, return

Solution

You have violated the Rule of Three.

Specifically, when you return an object, a copy is made, and then destroyed. So, you have a sequence of events like

Ctest1::Ctest1(void);
Ctest1::Ctest1(const Ctest1&);
Ctest1::~Ctest1();
Ctest1::~Ctest1();

That is two objects are created: your original object construction, followed by the implicit copy constructor. Then both of those objects are deleted.

Since both of those objects contain the same pointer, you end up calling `delete` twice on the same value. BOOM

Extra Credit: When I investigate issues like "I wonder how the copies get made", I put print statements in the interesting class methods, like this:

#include <iostream>

int serial_source = 0;
class Ctest1
{
#define X(s) (std::cout << s << ": " << serial << "\n")
  const int serial;
public:
   Ctest1(void) : serial(serial_source++) {
     X("Ctest1::Ctest1(void)");
   }
   ~Ctest1(void) {
    X("Ctest1::~Ctest1()");
   }
   Ctest1(const Ctest1& other) : serial(serial_source++) {
    X("Ctest1::Ctest1(const Ctest1&)");
    std::cout << " Copied from " << other.serial << "\n";
   }
   void operator=(const Ctest1& other) {
     X("operator=");
     std::cout << " Assigning from " << other.serial << "\n";
   }
#undef X
};

Ctest1 Function(Ctest1* cPtr){
   return *cPtr;    
}

int main()
{
   Ctest1* cPtr;

   cPtr=new Ctest1();


   for(int i=1;i<10;i++)
      *cPtr = Function(cPtr);

   delete cPtr;

   return 0;
}

Problem

I wanted to test how C++ behaves when the return value of a function is an object. I made this little example to watch how many bytes are allocated and determine whether the compiler makes a copy of object (like when object is passed as a parameter) or instead returns some kind of reference. However, I couldn't run this very simple program and I have no idea why. Error says: "Debug assertion failed! Expression: BLOCK_TYPE_IS_INVALID" in some dbgdel.cpp file. Project is a win32 console application. But I'm pretty sure that there is something wrong with this code. ``` class Ctest1 { public: Ctest1(void); ~Ctest1(void); char* classSpace; }; Ctest1::Ctest1(void) { classSpace = new char[100]; } Ctest1::~Ctest1(void) { delete [] classSpace; } Ctest1 Function(Ctest1* cPtr){ return *cPtr; } int _tmain(int argc, _TCHAR* argv[]) { Ctest1* cPtr; cPtr=new Ctest1(); for(int i=1;i<10;i++) *cPtr = Function(cPtr); delete cPtr; return 0; } ```

Original source

Related problems