-4

I'm trying to understand why the destructor is called in the following code.

I guess the function f() triggers somehow the destructor, but I can't figure out why.

#include <iostream>
using namespace std;

class c {
    int* p;

public:
    c() { p = new int(1); }
    void display() { cout << *p << endl; }
    ~c() { delete p; }
};

void f(c){};

void main() {
    c o;
    f(o);
    o.display();
    getchar();
}

The output is -572662307 and, at the end, this runtime exception is thrown: CrtIsValidHeapPointer(block). The destructor was called and the pointer at that specific address, deleted.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
Dani Ruse
  • 41
  • 1
  • 6
  • That's terrible formatting. The destructor is called because `f`''s argument is passed by value, so the local value is created and destroyed at the end of the function. `void main()` is not valid, return type of the main is `int`, not `void`. – Quimby Jul 04 '19 at 22:55
  • You need to keep reading your C++ book. You need to understand the concepts of copy constructors and Rule of Three in order for you fully understand what's going on here. – Sam Varshavchik Jul 04 '19 at 22:56
  • 1
    You pass by copy. So without user-definde copy constructor you'll get automatic generated one, which just copies the pointer. Then one destructor is called and pointer is deallocated, and then another for the same pointer, and you're getting heap corruption and exception – Severin Pappadeux Jul 04 '19 at 22:58

1 Answers1

1

f()'s input parameter is taken by value, so a copy of o gets made when f(o) is called. That copy is destructed when it goes out of scope when f() exits.

Your c class is violating the Rule of 3 by not defining a copy constructor or a copy assignment operator. So the copied c object inside of f() will end up holding the same p pointer value as the o object in main(). When the copy is destroyed, its destructor frees the int, leaving o in main() with a dangling pointer to invalid memory, and the subsequent call to o.display() will have undefined behavior. You need to implement proper copy sematics in your c class:

class c {
    int* p;

public:
    c() { p = new int(1); }
    c(const c &src) { p = new int(*(src.p)); }
    ~c() { delete p; }

    c& operator=(const c &rhs) { *p = *(rhs.p); return *this; }

    void display() const { cout << *p << endl; }
};
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770