C++ Destructors with Vectors, Pointers,

C++Destructor

C++ Problem Overview


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?

C++ Solutions


Solution 1 - C++

>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.

Solution 2 - C++

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;};
}

Solution 3 - C++

  • 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.

Solution 4 - C++

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

Solution 5 - C++

> 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.

Solution 6 - C++

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.

Solution 7 - C++

  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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionISTBView Question on Stackoverflow
Solution 1 - C++hmjdView Answer on Stackoverflow
Solution 2 - C++Alejandro AlcaldeView Answer on Stackoverflow
Solution 3 - C++Luchian GrigoreView Answer on Stackoverflow
Solution 4 - C++CubicView Answer on Stackoverflow
Solution 5 - C++AndreyView Answer on Stackoverflow
Solution 6 - C++user1607425View Answer on Stackoverflow
Solution 7 - C++user1434698View Answer on Stackoverflow