C++ delete vector, objects, free memory

C++VectorDelete Operator

C++ Problem Overview


I am totally confused with regards to deleting things in C++. If I declare an array of objects and if I use the clear() member function. Can I be sure that the memory was released?

For example :

tempObject obj1;
tempObject obj2;
vector<tempObject> tempVector;

tempVector.pushback(obj1);
tempVector.pushback(obj2);

Can I safely call clear to free up all the memory? Or do I need to iterate through to delete one by one?

tempVector.clear();

If this scenario is changed to a pointer of objects, will the answer be the same as above?

vector<tempObject> *tempVector;
//push objects....
tempVector->clear();

C++ Solutions


Solution 1 - C++

You can call clear, and that will destroy all the objects, but that will not free the memory. Looping through the individual elements will not help either (what action would you even propose to take on the objects?) What you can do is this:

vector<tempObject>().swap(tempVector);

That will create an empty vector with no memory allocated and swap it with tempVector, effectively deallocating the memory.

C++11 also has the function shrink_to_fit, which you could call after the call to clear(), and it would theoretically shrink the capacity to fit the size (which is now 0). This is however, a non-binding request, and your implementation is free to ignore it.

Solution 2 - C++

There are two separate things here:

  1. object lifetime
  2. storage duration

For example:

{
    vector<MyObject> v;
    // do some stuff, push some objects onto v
    v.clear(); // 1
    // maybe do some more stuff
} // 2

At 1, you clear v: this destroys all the objects it was storing. Each gets its destructor called, if your wrote one, and anything owned by that MyObject is now released. However, vector v has the right to keep the raw storage around in case you want it later.

If you decide to push some more things into it between 1 and 2, this saves time as it can reuse the old memory.

At 2, the vector v goes out of scope: any objects you pushed into it since 1 will be destroyed (as if you'd explicitly called clear again), but now the underlying storage is also released (v won't be around to reuse it any more).


If I change the example so v becomes a pointer to a dynamically-allocated vector, you need to explicitly delete it, as the pointer going out of scope at 2 doesn't do that for you. It's better to use something like std::unique_ptr in that case, but if you don't and v is leaked, the storage it allocated will be leaked as well. As above, you need to make sure v is deleted, and calling clear isn't sufficient.

Solution 3 - C++

vector::clear() does not free memory allocated by the vector to store objects; it calls destructors for the objects it holds.

For example, if the vector uses an array as a backing store and currently contains 10 elements, then calling clear() will call the destructor of each object in the array, but the backing array will not be deallocated, so there is still sizeof(T) * 10 bytes allocated to the vector (at least). size() will be 0, but size() returns the number of elements in the vector, not necessarily the size of the backing store.

As for your second question, anything you allocate with new you must deallocate with delete. You typically do not maintain a pointer to a vector for this reason. There is rarely (if ever) a good reason to do this and you prevent the vector from being cleaned up when it leaves scope. However, calling clear() will still act the same way regardless of how it was allocated.

Solution 4 - C++

> if I use the clear() member function. Can I be sure that the memory was released?

No, the clear() member function destroys every object contained in the vector, but it leaves the capacity of the vector unchanged. It affects the vector's size, but not the capacity.

If you want to change the capacity of a vector, you can use the clear-and-minimize idiom, i.e., create a (temporary) empty vector and then swap both vectors.


You can easily see how each approach affects capacity. Consider the following function template that calls the clear() member function on the passed vector:

template<typename T>
auto clear(std::vector<T>& vec) {
   vec.clear();
   return vec.capacity();
}

Now, consider the function template empty_swap() that swaps the passed vector with an empty one:

template<typename T>
auto empty_swap(std::vector<T>& vec) {
   std::vector<T>().swap(vec);
   return vec.capacity();
}

Both function templates return the capacity of the vector at the moment of returning, then:

std::vector<double> v(1000), u(1000);
std::cout << clear(v) << '\n';
std::cout << empty_swap(u) << '\n';

outputs:

1000
0

Solution 5 - C++

Move semantics allows for a straightforward way to release memory, by simply applying the assignment (=) operator from an empty rvalue:

std::vector<int> vec(100, 0);
std::cout << vec.capacity(); // 100

vec = vector<int>();         // Same as "vector<int>().swap(vec)";    
std::cout << vec.capacity(); // 0

It is as much efficient as the "swap()"-based method described in other answers (indeed, both are conceptually doing the same thing). When it comes to readability, however, the assignment version makes a better job.

Solution 6 - C++

You can free memory used by vector by this way:

//Removes all elements in vector
v.clear()

//Frees the memory which is not used by the vector
v.shrink_to_fit();

Solution 7 - C++

If you need to use the vector over and over again and your current code declares it repeatedly within your loop or on every function call, it is likely that you will run out of memory. I suggest that you declare it outside, pass them as pointers in your functions and use:

my_arr.resize()

This way, you keep using the same memory sequence for your vectors instead of requesting for new sequences every time. Hope this helped. Note: resizing it to different sizes may add random values. Pass an integer such as 0 to initialise them, if required.

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
QuestionmisterView Question on Stackoverflow
Solution 1 - C++Benjamin LindleyView Answer on Stackoverflow
Solution 2 - C++UselessView Answer on Stackoverflow
Solution 3 - C++Ed S.View Answer on Stackoverflow
Solution 4 - C++ネロクView Answer on Stackoverflow
Solution 5 - C++Ronald SouzaView Answer on Stackoverflow
Solution 6 - C++BensuperpcView Answer on Stackoverflow
Solution 7 - C++user3715882View Answer on Stackoverflow