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; } ```