13

Does the default destructor in C++ classes automatically delete members that are not explicitly allocated in code? For example:

class C {
  public:
    C() {}
    int arr[100];
};

int main(void) {
  C* myC = new C();
  delete myC;
  return 0;
}

Does delete myC deallocate myC's arr automatically? Or do I need to write C's destructor to do this explicitly?

Robz
  • 1,747
  • 5
  • 21
  • 35

5 Answers5

12

The constructor (in the absence of any ctor-initializer-list) calls the default constructor for each subobject.

Since you have no base classes and your member variables are primitive types, it will do nothing at all.

Same with the destructor. Yours is implicitly compiler-generated since you haven't declared one, and it will call the destructor for each subobject. Again that's trivial because your only subobject is an aggregate of primitives.

Now, all memory of the class will be freed when you delete it. Since the array is embedded inside the class, it's part of the same memory region and will be freed at the same time.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
6

The implicitly defined (default) destructor will call the destructor for each member. In the case of a member array, it will call the destructor for each element of the array.

Note that pointers don't have destructors; you need to manually delete them. You don't have this problem in the provided example, but it's something to be aware of.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • 1
    Pointers kind of have destructors [(see here)](http://ideone.com/97iUx), although obviously they don't delete what they point to. – Pubby Mar 31 '12 at 03:36
  • wait... you say pointers don't have destructors, but I thought delete only takes a pointer. you're saying that the default destructor would call delete on every 100 ints in the array? – Robz Mar 31 '12 at 03:37
  • @Robz, No - I'm saying the implicit destructor *doesn't* call delete, you have to do that yourself in an explicit destructor if you have any raw pointers as members. – Mark Ransom Mar 31 '12 at 03:40
  • `delete` only works on pointers. The 100 `int` members of this class will be destroyed, via `int::~int()`, not via `delete`. And `int::~int()` does nothing at all, it's trivial, just like all primitive types (including pointers). – Ben Voigt Mar 31 '12 at 03:41
  • @Pubby, pointers don't have destructors - they *call* destructors when they're deleted. Different thing altogether. – Mark Ransom Mar 31 '12 at 03:47
  • @BenVoigt, 100% correct. Even better, the compiler will realize that `int::~int()` is empty and not generate any code for it whatsoever. – Mark Ransom Mar 31 '12 at 03:48
  • @Mark: I think Pubby is saying that (ordinary primitive) pointer types have destructors much the same way as `int::~int()` exists -- to make it possible to write template code with explicit destructor calls (think of `std::vector::resize()`. But destructors for pointer types do nothing, and just like you said about `int::~int()`, the compiler knows that and won't generate a function call. – Ben Voigt Mar 31 '12 at 04:06
5

If your class/struct contains a pointer, and you explicitly allocate something for that pointer to refer to, then you normally need to write a matching delete in the dtor. Members that are directly embedded into the class/struct will be created and destroyed automatically.

class X { 
    int x; 
    int *y;
public:
    X() : y(new int) {}
    ~X() : { delete y; }    
};

Here X::x will be created/destroyed automatically. X::y (or, to be technically correct, what X::y points at) will not -- we allocate it in the ctor and destroy it in the dtor.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • 1
    `X::y` is destroyed automatically. It's `*(X::y)` that would leak if it weren't for the destructor. (And your sample breaks the Rule-of-Three/Four/Five) – Ben Voigt Mar 31 '12 at 03:43
  • @BenVoigt: Yes -- the question was about what the destructor does, not how to write a class that correctly handles remote ownership. – Jerry Coffin Mar 31 '12 at 04:00
0

Anything that you call new for must have a corresponding delete. If you didn't call new to create an instance of something then you don't have to call delete.

Cramer
  • 1,785
  • 1
  • 12
  • 20
  • IMHO, you should rarely `delete` anything in application-code. Instead, try to establish strict ownership or member-of semantics for all members, such that automatic destruction does the trick. Should that fail, smart-pointers are often a better alternative to manual pointers and `delete`. – Rawler Mar 31 '12 at 19:51
-2

You don't have to write a destructor. C++ class has the default destructor to delete the object after 'return 0' to recycle the memory.

bruce
  • 29
  • 3