简体   繁体   中英

C++ Memory management for vector of Objects

I have a few questions/examples about how memory management works for Vectors.

    vector<int> vec1(10);
    vector<int> vec2(10);        
    vec1 = vec2;

In a case like this, vec1's old memory is unreachable now. Is it still a memory leak here or would vec2's old memory realize there nothing referencing it and get cleaned up?

In another example

struct foo
{
   vector<int> foo_vec(50);
   int* arr; 
}


void myFunction()
{
   vector<foo> vec(10);
   vec[0].arr = new int[50];
   vec.erase(vec.begin());
}

Since I used erase() on the first vector element which contained arr with the allocated memory, does erase() release that memory or do I need to release it manually prior to the erase? Also when vec goes out of scope, are all the foo_vec vectors in vec automatically cleaned up? Thanks for any help.

Does erase() release that memory or do I need to release it manually prior to the erase?

The rule: Always use delete for each new . vector ain't no magic - it doesn't know how you obtained that pointer, so it won't delete it, you need to do it.

Also when vec goes out of scope, are all the foo_vec vectors in vec automatically cleaned up?

Yes, their destructor is called and they're deallocated. However, you will leak memory if the destructor doesn't delete[] arr; .


By the way, a piece of good advice: your code violates encapsulation. You should allocate ( new ) and free ( delete[] ) the memory pointed to by foo::arr in the destructor and the constructor ( foo::foo() and foo::~foo() ), respectively.

Finally, the obligatory question: why foo::arr isn't a vector<int> itself?

In the case of

vector<int> vec1(10);
vector<int> vec2(10);        
vec1 = vec2;

the previous contents of vec1 are erased since int is just a POD. If the vector consisted of pointers to objects instead of ints and these were allocated with new you would have to delete what those pointers point to before you assign, otherwise you would end up with memory leaks which your second example shows:

vector<foo> vec(10);
vec[0].arr = new int[50];
vec.erase(vec.begin());    // this will *not* call delete on vec[0].arr

Normally what you do to make things simpler for yourself is to use smart pointers like unique pointers (or eg boost::shared_array/scoped_array). When the vector goes out of scope or you erase the vector the delete (or delete []) will be automatically called.

struct foo
{
   std::vector<int> foo_vec(50);
   std::unique_ptr<int[]> arr; 
}
...
vec[0].arr.reset(new int[50]);
vec[0].arr[12] = 42;
...
vec.erase(vec.begin());    // this will call delete[] on vec[0].arr
  1. Of course it will be cleaned.
  2. No, if destructor of foo doesn't do this (or if you don't do it manually before erase).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM