0

I am reading a textbook and it seems to indicate that when you have a member variable that's a pointer, you have to put code in the destructor in order to delete the memory.
It's a little unclear but it seems that the code has to look like this:

private:  
double *aPtr;

public:  
~NumberArray(){ delete [ ] aPtr;}

Doesn't this end up being 2 delete commands, though, because the destructor is already deleting the first element in that array? Also, do destructors automatically do their default work, even if you have 1 or more lines in your program for the default destructor? Does the program execute your code first or it executes the code the "automatic" part of the destructor?

For some reason I thought that the delete command is just used for dynamically allocated memory. I guess I am wrong about that?

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • 1
    "*when you have a member variable that's a pointer, you have to put code in the destructor in order to delete the memory*", why? A pointer doesn't have to point to memory that must be "deleted". – juanchopanza Nov 22 '17 at 07:34
  • *"the destructor is already deleting the first element in that array"* - where is it doing that? Your destructor is only calling the `delete[]` operator. Also you don't have a default destructor because you overloaded it – UnholySheep Nov 22 '17 at 07:36
  • The destructor will delete the pointer itself. As a pointer is [plain old data](https://stackoverflow.com/a/146454/7478597), it does actually nothing. Whether you have to add a `delete` for the _contents_ the pointer is pointing to depends. If the class "owns" the pointed contents (and does not share it with other owners) it should. Otherwise, it should not. And, please, consider whether to use `delete` or `delete[]` depends on the contents the pointer is pointing to. – Scheff's Cat Nov 22 '17 at 07:38
  • Btw. destructor and `delete` are separate things. Though, a `delete` calls the destructor for the pointed object (assuming a non-`nullptr`), the destructor is also called for any other constructed object. A class which is instanced as local variable is destructed when "going out of scope" - `delete`-ing it would be illegal. A constructed object in a global variable is destructed after leaving `main()` - again no `delete`. Not to mention explicit destructor calls for instances which are constructed with [placement `new`](https://stackoverflow.com/a/222578/7478597)... – Scheff's Cat Nov 22 '17 at 07:52
  • You might be confusing "a pointer to the first element of an array" with "the first element of an array". – molbdnilo Nov 22 '17 at 07:59

2 Answers2

2

Doesn't this end up being 2 delete commands, though, because the destructor is already deleting the first element in that array?

The destructor is destructing the pointer (which is a no-op). But it doesn't at all touch what the pointer is pointing at. So there isn't any delete operation going on unless you explicitly write one yourself.

Also, do destructors automatically do their default work, even if you have 1 or more lines in your program for the default destructor?

Yes, destructors will always destroy the members and bases of the object (after the destructor body is executed). But again, the member is aPtr. It's not whatever aPtr is pointing at.

Does the program execute your code first or it executes the code the "automatic" part of the destructor?

Any member of the object is still alive during the destructor body. Which makes sense, since they may be required for cleanup related operations. After that, they are indeed destroyed.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
-1

You seem a bit confused about what the difference between delete and delete[].

The first form of delete (without the brackets), is used to destroy dynamic memory allocated for a single object. This form should not be used on arrays, since in that case, the compiler will call the destructor only once.

The second form, with square brackets, guarantees that the destructor will be called for each element of a dynamically allocated array, before the memory used for the array is itself released.

In short:

// first form:
SomeClass* object = new SomeClass;
delete object;                     // SomeClass::~SomeClass is called once, which is good.

// second form
SomeClass* array = new SomeClass[N]; // SomeClass::SomeClass() is called N times.
delete[] array;      // SomeClass::~SomeClass is called N times, which is good.
delete array;        // YIKES!! SomeClass::~SomeClass is called only once. 
                     // This is terrible, as N-1 destructors did not get called.
Michaël Roy
  • 6,338
  • 1
  • 15
  • 19