-2

Destructor is invoked during exit of scope or delete, etc. It aims to return dynamic allocated resource to the pool. When I call destructor (empty destructor) explicitly, will it / what does it do anything on class members?

It is not a question seeking help on debug, Example Code:

  class Z(){
    public:
      Z(){ };
      ~Z(){ };
      int count {0};
  }

  void main()
  {
      Z* z = new Z();
      z->count = 1;
      z->~Z();
      cout << z->count << endl;
  }

It seems to me that z->count stay alive after the call of destructor during my test. Calling destructor explicitly does not return the resource of object to heap. I would like to double check if it is the expected behaviour

I guess calling destructor z->~Z() directly is different to "delete z", one will only execute what implemented in ~Z(), later will do ~Z() and then delete the class members.

Kelvin Lai
  • 79
  • 4

3 Answers3

6

The destructor is just a piece of code to be executed before the memory of the class is returned to the heap or stack. It in itself does not de-allocate the memory used by the class, but should be used to clean up any allocations you may of done in the constructor.

If you have created the class via new, you should call delete and not the destructor directly. delete will return the memory of the class to the heap after it has called the destructor for you.

ChrisW
  • 76
  • 4
3

The memory to which pointer key points will "stay alive", although you probably loose any relation to it once the respective Z-object has been destructed. So you are leaking memory here. To avoid this, add a destructor, i.e. ~Z() { delete[] key; }.

The members of a Z, i.e. key and count, must not be accessed once the owning object has been destructed. It might be that the "values" of these data members are not "cuttet out of system's memory", but you must not access them any more.

And regarding calling the destructor through z->~Z(): This is very unusual and very likely to be wrong unless you aim to manage memory on your own and you are very aware of what you are doing.

Usually, i.e. in probably 99.9999% of all cases you code, the destructor shall be triggered implicitly whenever an object is to be destructed when it's life time ends, i.e. for automatic variables when going out of scope and for dynamically allocated objects when explicitly calling delete z.

So a (slightly) better version of your program would be:

class Z {
public:
    Z(){ key = new char[10]; }
    ~Z(){ delete[] key; }
    char* key;
    int count {0};
};

int main() {
    Z* z = new Z();
    z->count = 1;
    z->key[0] = 'K';
    delete z;
}

It's only "slightly" better, because the class still does not cover when a Z-object is copied or moved (look at Rule of 3/5 when allocating memory on your own).

So I'd suggest to do it the following way:

#include <string>
class Z {
public:
    std::string key;
    int count {0};
};

int main() {
    Z z;
    z.count = 1;
    z.key = "K";
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
-1

For every new, there should be delete.

You are manually allocating a memory chunk on the heap in your constructor. Hence, you have to manually delete it:

Class Z(){
public:
  char* key;
  int count {0};

  Z(){
      key = new char[10];
  };

  ~Z(){
      delete[] key;
  };
Lucas Kahlert
  • 1,207
  • 9
  • 16