Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A few memory management questions involving class destructors and delete operator?

After reading some tutorials I am still unclear on some points about memory management in C++.

1. when a class declared with the new operator goes out of scope is its destructor called and memory freed? Is it necessary to call the delete operator to free the class' memory and have its destructor called?

class Test{};

void newTest(){
    Test *t = new Test;
}

int main()
{
    newTest();
    return 0;
}

2. Are variables (such as a vector) declared with the new keyword freed when the class they reside within is destroyed? Do those variables have to be explicitly deleted in the class's destructor?

class Test{
    vector<int> *vec;
public:
    Test();
};

Test::Test(){
    *vec = new vector<int>;
}

void newTest(){
    Test t;
}

int main()
{
    newTest();
    return 0;
}

3. Same as question 2, but with normal variables declared on the stack. In the following example, is the vector vec deleted when t goes out of scope?

class Test{
    vector<int> vec;
};

void newTest(){
    Test t;
}

int main()
{
    newTest();
    return 0;
}

4. Finally, which is the better way to declare a vector in a class, normally (on the stack) or with the new keyword (on the heap)?

like image 802
stack356 Avatar asked Feb 24 '23 16:02

stack356


2 Answers

It sounds like you may come from a Java background, so things with new work a bit differently in C++.

  1. The memory allocated with new must be explicitly destroyed with delete. This example has a memory leak.

  2. Similar to question 1, you must delete the memory in the class destructor to reclaim it.

  3. In this case the vector will be destructed automatically.

  4. Within a class, always prefer to store members by value (as opposed to with new) unless you have a specific reason to do otherwise. Just because it's stored by value within the class doesn't mean it's on the stack, it's in the same region of memory that the containing class occupies.

Finally note that in C++ you can use RAII to make memory management much less error prone. Take a look at shared_ptr, scoped_ptr, and unique_ptr for example. These all handle automatically freeing the newly allocated memory when appropriate.

like image 134
Mark B Avatar answered Apr 08 '23 09:04

Mark B


  1. No, the destructor is not called and the memory is not freed. you have to delete the object.
  2. No, the variables are not freed. You have to delete them in the destructor.
  3. Yes, vec is deleted (the destructors are called and the memory is freed).
  4. Usually on the stack is better, when possible. It may not be possible if, for example, the ownership of the object is passed to another object. Also, one should not allocate too much memory on the stack (the OS has limits on this), in which case the object should be allocated on the heap.
like image 39
Antti Avatar answered Apr 08 '23 08:04

Antti