0

Here's what I had:

// define structures A & B...
// Brief example of the functions:
struct B* foo(const struct A mystruct)
{
    struct B *outstruct = new S();
    // Copying values from structure A to B
    return(outstruct);
}
int main()
{
    struct A *mystruct = new A();
    struct B *tmp = foo(*mystruct);
    delete(A); delete(B);
    return 0;
}

I kept getting a core dump message, so I put a printf statement in the destructor of A. It showed that the destructor was called twice: (1) at the end of main, as expected, and (2) at the end of foo.

So, I changed the foo function to pass mystruct as a pointer (making the necessary syntax changes) and the destructor was called only once, at the end of main as desired. What is the reason for this? Or might I be missing something else?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
KEH
  • 3
  • 3
  • 1
    Your argument has a non-reference type, so it is pass-by-value, and a copy will be made. Then the copy will be destroyed, using the destructor. – Ben Voigt Apr 30 '14 at 22:17
  • 4
    BTW, it seems you are writing Java code in C++. Try to break that habit. Good C++ code rarely uses the `new` operator. Just use local non-pointers variables in most cases. – Ben Voigt Apr 30 '14 at 22:18
  • possible duplicate of [What is The Rule of Three?](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) and also of http://stackoverflow.com/questions/5268342/c-double-free-errors-when-using-shallow-copies-of-objects-how-to-fix – Ben Voigt Apr 30 '14 at 22:20
  • @BenVoigt Just an example. I need to create it the structure on the stack for my actual application. – KEH Apr 30 '14 at 22:25
  • If you're starting out with C++ you will learn, live and love RAII. – dutt Apr 30 '14 at 22:31
  • I think you copied `struct *B foo(const struct A mystruct)` incorrectly as it's not valid C++ proably you meant `struct B* foo(const struct A mystruct)` or as is more typically seen just `B *foo(const A mystruct)` – PeterSW Apr 30 '14 at 22:33

2 Answers2

1

The function struct B* foo(const struct A mystruct) passes A by value. So mystruct in the function is a copy of the one in main. The destructor therefore is called on it when the program flow leaves the function.

If instead you pass:

  • by pointer: B *foo(const A *mystruct) or
  • by reference: B *foo(const A &mystruct)

Then no copy is made of an A so there is no destructor call for an A on leaving the function.

If A were implemented correctly then the pass by value version should not core-dump. Though to understand why it core-dumps we'd need to see more of the code.

PeterSW
  • 4,921
  • 1
  • 24
  • 35
  • As someone who uses Matlab 80% of the time, silly me :). That's why it worked when I used a pointer. Thanks! – KEH Apr 30 '14 at 22:27
  • @KEH As R Sahu points out something is wrong in `A` to cause the pass by value version to core dump. – PeterSW Apr 30 '14 at 22:35
0

When you call foo, a temporary object is constructed from *mystruct by calling the copy constructor. The temporary object is destructed when you return from foo. The core dump is caused by mismanaged memory in A.

R Sahu
  • 204,454
  • 14
  • 159
  • 270