10

If I have a class that looks something like this:

class SomeClass {
    public:
        SomeClass(int size) {
                     arr = new int[size];
                     someInt = size / 10;
                    };
        ~SomeClass() {
                      delete [] arr;
                      //do I need to somehow delete the int value 'someInt'?
                     };
    private:
        int *arr; //pointer to dynamically allocated array
        int someInt;
}

What, exactly, should be contained in the destructor to avoid memory leaks?

I am aware that I need to delete the array, since it is dynamically allocated, but do I need to do anything with int values, or other basic data types?

Thanks, Jonathan

Jonathan
  • 541
  • 4
  • 9
  • 19
  • 4
    No -- and you should be using `std::vector` instead of allocating the space manually. – Jerry Coffin Apr 18 '13 at 18:55
  • [Not so related, but recommended Q&A](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list?rq=1) :) – jrok Apr 18 '13 at 18:57
  • @Jerry, this is relating to a school assignment where I am required to use a dynamically allocated array as a portion of it. I am also required to deconstruct everything in the class properly. – Jonathan Apr 18 '13 at 18:57
  • 1
    Keep the rule of three or five in mind, too. It isn't followed in your sample code. – chris Apr 18 '13 at 19:16
  • @chris, being unfamiliar with the rule by name - I looked it up. I merely threw this together as a brief example. In my actual class, I do have a default (null) constructor and a copy constructor. I have not been taught about move constructors yet. I would be happy to read through an explanation, if you feel a desire to PM one to me. =) – Jonathan Apr 18 '13 at 19:30
  • You only need to worry about the move forms if you're using C++11, but they're for when the old object shouldn't be used after. For example, `std::vector`'s move constructor and move assignment operator will just copy the pointer instead of the elements, and set the other object's pointer to `nullptr`. It's meant for temporaries that are about to be destroyed, so things don't have to get copied more than they need to. In C++03, all you need to care about are the destructor, copy constructor, and copy assignment operator. – chris Apr 18 '13 at 19:35
  • I should mention as well that when I went into specifics about `std::vector`'s move constructor, I was using it as an example. I don't think you can actually count on that behaviour for vectors (among other things), but you shouldn't be trying to use a moved-from object anyway. It would have worked better if I used a custom vector class as an example. – chris Apr 19 '13 at 01:08

6 Answers6

24

No.

But not just for basic types. For anything that you didn't allocate with new you don't have to call delete on. Even for pointers.

delete has (somehow) nothing to do with the member variable type. What matters is if you have allocated it (with new) in your constructor (or somewhere else in your class methods).

The rule of thumb is

Have as many delete as new
Have as many delete[] as new[].

Of course sometimes you will have to delete something you haven't allocated but are pointing to if it is not needed anymore (allocated by someone else but you are the only one using it).

Of course sometimes you will have to NOT delete something you HAVE allocated but someone else is pointing to (allocated by you but someone else is using it).

stardust
  • 5,918
  • 1
  • 18
  • 20
  • 1
    Just because a class didn't allocate something, doesn't mean it doesn't 'own' something that should be deleted when the class is destroyed. –  Apr 18 '13 at 18:59
  • @James Yes. True. But that is not what he is asking. I am just trying to specify the basics of it. I will edit it. – stardust Apr 18 '13 at 19:00
  • So in other words, in this particular case, I only need to delete the array, as I already have? And as @James pointed out, there may be occasions where the delete might happen somewhere besides the destructor in the class where the allocation occurred? – Jonathan Apr 18 '13 at 19:01
  • 1
    @Jonathan In this case you only have to delete the array. Nothing more. The other cases I think you will notice them when you need them. See my edit. – stardust Apr 18 '13 at 19:04
  • 1
    @Jonathan Yes, that's correct. Exactly when and where you delete something is entirely down to the design of your program. For basic allocated memory it's down to you to decide who owns what, and who is responsible for cleaning up any given resource. Most often, it's true that the class that allocates something is the one responsible for deleting it. There are always exceptions, but what they are is completely under your control. –  Apr 18 '13 at 19:04
  • @James I have edited it to be general. I think it covers it somehow now. – stardust Apr 18 '13 at 19:07
  • 1
    Thanks, guys. Between this post, and dascandy's, it makes sense to me now. =) – Jonathan Apr 18 '13 at 19:09
5

No, you don't have to manually delete automatic variables. Only delete what you new.

Additionally, you can avoid the need to delete the array by using RAII via a smart pointer. Then you won't have to manually define a destructor; the automatically defined destructor will do what you need.

class SomeClass {
    public:
        SomeClass(int size)
          : arr {new int[size]}
          , someInt = size/10;
        {};

    private:
        std::unique_ptr<int[]> arr; //pointer to dynamically allocated array
        int someInt;
}

It's even better to use a more specialized type such as std::vector instead of a generic smart pointer:

class SomeClass {
    public:
        SomeClass(int size)
          : arr (size)
          , someInt = size/10;
        {};

    private:
        std::vector<int> arr;
        int someInt;
}
bames53
  • 86,085
  • 15
  • 179
  • 244
  • I agree with both cases, and definitely the fact that using vectors would simplify what I am trying to do - but this is regarding a class assignment where both of your solutions are forbidden. I need to explicitly deconstruct the array, and I cannot use vectors. =P – Jonathan Apr 18 '13 at 19:07
  • @Jonathan If you're not allowed to use the `std` facilities you might try creating a simple implementation of them yourself. Manually managing resources without such helpers is difficult to get right. You might even learn more that way. – bames53 Apr 18 '13 at 19:13
  • I think one of the main purposes of this assignment IS to understand deconstructors and proper memory allocation and management (to a small scale at least). I don't need to use it again beyond this case, but I do need to demonstrate I understand it. Otherwise, believe me, I would be far happier using vectors. =) – Jonathan Apr 18 '13 at 19:24
  • Right, but what I mean is you can learn that by developing the helper components; unless your program only has to manage one thing then it's easier to write a helper component and use it more than once than it would be to duplicate the helper's logic multiple times. If your program only manages one pointer then it doesn't matter. – bames53 Apr 18 '13 at 19:30
  • I only need to manage the one pointer in this program. In the future, when I need to manage more, I will be able to use vectors. – Jonathan Apr 18 '13 at 19:35
4

No, you don't. You only delete what was allocated using new.

3

You never delete or new anything that's a part of your object. That sentence immediately indicates why you don't do anything specific for the int, but you do something for the pointer.

The int itself is part of your class. The pointer is part of your class. In fact, all things listed in your class themselves are a part of your class. The point to note is that the pointer is a part of your class, but the pointee or pointed-at object is not. The pointer as such will be destroyed (and have its destructor called, if relevant) but the pointee will not.

dascandy
  • 7,184
  • 1
  • 29
  • 50
  • Thank you for clarifying that. I think the need for explicitly destroying the pointed-to object now makes far more sense to me. I'd give you the answer, but I think user's answer more closely answers my question. Have a +1 though. =) – Jonathan Apr 18 '13 at 19:05
2

No. someInt is stored by value and uses automatic storage duration. Once the object it belongs to is destroyed someInt and all other member variables with automatic storage duration are destroyed as well. You are still responsible for managing objects with dynamic storage duration (new/delete) which you have already done.

Captain Obvlious
  • 19,754
  • 5
  • 44
  • 74
1

You only need to delete what you new or delete[] what you new[]. You may want to look into auto_ptr

brent.payne
  • 5,189
  • 3
  • 22
  • 17