53

As far as I know, I should destroy in destructors everything I created with new and close opened filestreams and other streams. However, I have some doubts about other objects in C++:

  • std::vector and std::strings: Are they destroyed automatically?

  • If I have something like

    std::vector<myClass*> 
    

    of pointers to classes. What happens when the vector destructor is called?
    Would it call automatically the destructor of myClass? Or only the vector is destroyed but all the Objects it contains are still existant in the memory?

  • What happens if I have a pointer to another class inside a class, say:

    class A {
      ClassB* B;
    }
    

    and Class A is destroyed at some point in the code. Will Class B be destroyed too or just the pointer and class B will be still existent somewhere in the memory?

hmjd
  • 120,187
  • 20
  • 207
  • 252
ISTB
  • 1,799
  • 3
  • 22
  • 31
  • 2
    "Or only the vector is destroyed but all the Objects it contains are still existant in the memory?" - fix your thinking here. The objects contained by a `vector` are `myClass*` objects, that is to say objects of pointer type. They are destroyed when the vector is destroyed, but destroying a pointer does not affect the object that the pointer points to. So the objects that the vector contains are *not* still existent in memory. Imagining that the objects pointed to by the pointers are "contained in the vector" is obstructing you from being able to answer your own question :-) – Steve Jessop Aug 22 '12 at 08:33
  • 1
    Incidentally, you should use the `add comment` links below each answer to respond to them or ask for clarification. Don't use the `Post Your Answer` link! – Rook Aug 22 '12 at 09:01

7 Answers7

57

std::vector and std::strings: Are they destroyed automatically?

Yes (assuming member variables are not pointers to std::vector and std::string).

If I have something like std::vector what happens when the vector destructor is called? Would it call automatically the destructor of myClass? Or only the vector is destroyed but all the Objects it contains are still existant in the memory?

If vector<MyClass> then all objects contained in the vector will be destroyed. If vector<MyClass*> then all objects must be explicitly deleted (assuming the class being destructed owns the objects in the vector). A third alternative is vector of smart pointers, like vector<shared_ptr<MyClass>>, in which case the elements of the vector do not need to be explictly deleted.

What happens if I have a pointer to another class inside a class

The B must be explicitly deleted. Again, a smart pointer could be used to handle the destruction of B.

hmjd
  • 120,187
  • 20
  • 207
  • 252
  • shared_ptr is not provided. should I download something? Boost? – ISTB Aug 22 '12 at 08:24
  • @ISTB, yes. There is `boost::shared_ptr` and `boost::scoped_ptr`. C++11 added smart pointers `std::shared_ptr` and `std::unique_ptr` (`#include `). – hmjd Aug 22 '12 at 08:28
  • 1
    By the way, if I am using shared_ptr, how can I use new? I think that shared_ptr a = new ClassA(); will not work – ISTB Aug 22 '12 at 08:42
  • @ISTB, you `shared_ptr a(new ClassA());` or `shared_ptr a = make_shared();` – hmjd Aug 22 '12 at 08:47
  • And what happens if later I have a vector> in whicH I push the ClassA objects by using shared_ptr a(new ClassA()); and then I call vector.clear(), will it destroy the ClassA objects created by new and pushed into the vector? – ISTB Aug 22 '12 at 09:49
8

You only need to worry about for the memory you have created dynamically (When you reserve memory with new.)

For example:

Class Myclass{
   private:
       char* ptr;
   public:
       ~Myclass() {delete[] ptr;};
}
Alejandro Alcalde
  • 5,990
  • 6
  • 39
  • 79
  • if the class member is pointer and public, is it better "new" and "delete" in the same class ? (Because it's more clearly to read the code) – Thomas Mar 04 '20 at 08:02
3
  • if they are in automatic storage, yes. You can have std::string* s = new std::string, in which case you have to delete it yourself.

  • nothing, you need to manually delete memory you own (for memory allocated with new).

  • if you allocated b with new, you should destroy it in the destructor explicitly.

A good rule of thumb is to use a delete/delete[] for each new/new[] you have in your code.

A better rule of thumb is to use RAII, and use smart pointers instead of raw pointers.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
3

It depends. std::vector and std::string and MyClass all have 1 thing in common - if you declare a variable to be any of those types, then it will be allocated on stack, be local to the current block you're in, and be destructed when that block ends.

E.g.

{
    std::vector<std::string> a;
    std::string b;
    MyClass c;
} //at this point, first c will be destroyed, then b, then all strings in a, then a.

If you get to pointers, you guessed correctly: Only the memory the pointer itself occupies (usually a 4 byte integer) will be automatically freed upon leaving scope. Nothing happens to the memory pointed to unless you explicitly delete it (whether it's in a vector or not). If you have a class that contains pointers to other objects you may have to delete them in the destructor (depending on whether or not that class owns those objects). Note that in C++11 there are pointer classes (called smart pointers) that let you treat pointers in a similar fashion to 'normal' objects:

Ex:

{
    std::unique_ptr<std::string> a = make_unique<std::string>("Hello World");
    function_that_wants_string_ptr(a.get());
} //here a will call delete on it's internal string ptr and then be destroyed
Mankarse
  • 39,818
  • 11
  • 97
  • 141
Cubic
  • 14,902
  • 5
  • 47
  • 92
  • 2
    How can `make_unique("Hello World")` ever result in a `std::unique_ptr` (without crazy expression template stuff)? Did you mean `make_unique("Hello World")` (assuming a sane `make_unique` function)? – Mankarse Aug 22 '12 at 08:32
  • Sorry, my fault just somehow assumed that would exist. There's a sane implementation that's not crazy though http://stackoverflow.com/questions/7038357/make-unique-and-perfect-forwarding – Cubic Aug 22 '12 at 08:38
  • That still requires you to specify the type to be constructed by `make_unique`. – Mankarse Aug 22 '12 at 08:40
  • Yep, that was an oversight of mine. – Cubic Aug 22 '12 at 08:48
2

If I have something like std::vector what happens when the vector destructor is called?

It depends.

If you have a vector of values std::vector <MyClass>, then the destructor of the vector calls the destructor for every instance of MyClass in the vector.

If you have a vector of pointers std::vector <MyClass*>, then you're responsible for deleting the instances of MyClass.

What happens if I have a pointer to another class inside a class

ClassB instance would remain in memory. Possible ways to have ClassA destructor to make the job for you are to make B an instance member or a smart pointer.

Andriy
  • 8,486
  • 3
  • 27
  • 51
  • So, practically the only problem is when I use pointers. As long as I use them, I have to destroy everything myself. Except if I am using smart pointers – ISTB Aug 22 '12 at 08:26
  • @ISTB. You're right. See the answer from Luchian Grigore for a better explanation. – Andriy Aug 22 '12 at 08:28
  • 2
    @ISTB: The problem is when you use raw *owning* pointers to dynamically allocated objects, which you should never be doing, in a vector or otherwise. Owning pointers should always be smart pointers, but raw pointers can still be used as non-owning reassignable references. – Benjamin Lindley Aug 22 '12 at 08:31
1

std::vector, std::string and as far as I know all other STL containers have automatic destructors. This is the reason why it is often better to use these containers instead of new and delete since you will prevent memory leaks.

Your myClass destructor will only be called if your vector is a vector of myClass objects (std::vector< myClass >) instead of a vector of pointers to myClass objects (std::vector< myClass* >).

In the first case the destructor of std::vector will also call the destructor of myClass for each of its elements; in the second case the destructor of std::vector will call the destructor of myClass*, which means it will free the space taken to store each pointer but will not free the space taken to store the myClass objects themselves.

The Class B objects you point to will not be destroyed, but the space assigned to store its pointer will be freed.

1
  1. Yes. std::vector and std::stringare automatically when they finish out of scope, calling also the destructor of the objects contained (for std::vector).

  2. As said before, std::vectoris destroyed when it finish out of scope, calling the destructor of the objects contained. But in fact, in this case, the objects contained are the pointers, not the object pointed by the pointers. So you have to delete them manually.

  3. The same as (2). A will be destroyed and so the pointer, but not the class B pointed. You have to provide a destructor for A that delete B.

In C++11 there is a very useful solution: use std::unique_pointer. Can be use only to point a single object and this will be deleted when the pointer goes out of scope (for example when you destroy your std::vector).

http://en.cppreference.com/w/cpp/memory/unique_ptr