Right way to deallocate an std::vector object
The simplest and most reliable way to deallocate a vector is to declare it on the stack and simply do nothing.
void Foo() {
std::vector<int> v;
...
}
C++ guarantees that the destructor of v
will be called when the method executes. The destructor of std::vector
will ensure any memory it allocated is freed. As long as the T
type of the vector<T>
has proper C++ deallocation semantics all will be well.
Deallocating objects stored in a vector?
It depends on how vector is defined.
If maps is a vector<myClass*>
you delete each element with something similar to:
for ( i = 0; i < maps.size(); i++)
{
delete maps[i];
}
If maps is a vector<myClass>
I don't think you need to delete the individual elements.
How to correctly deallocate a c++ vector?
My thought process is that I'm using a
Set *aSet = new Set;
in my main class and since an int is not an object, it's not being freed when I call list.clear(). Is this right? How would I go about deleting the memory correctly?
No. To delete the memory you allocate correctly you need to call delete:
Set *aSet = new Set;
delete aSet;
However manually managing memory like this is difficult and error prone. You should prefer alternatives. The first is that you should not use dynamic allocation at all. You should simply use automatic variables:
Set aSet;
// no delete required. Variable destroyed/deallocated when it goes out of scope.
If you really do need dynamic allocation you should use smart pointers.
std::unique_ptr<Set> aSet(new aSet);
Smart pointers implement RAII for dynamic allocation so you don't have to do it manually.
In some rare circumstances you may actually need to do dynamic allocation manually, but that's an advance topic.
std::vector<T>::clear()
is not required to deallocate the vector's memory. You can use the C++11 member function shrink_to_fit()
, or you can use the swap trick:
std::vector<int> list;
...
std::vector<int>(list).swap(list);
Also you really shouldn't be using a pointer to a vector. A vector uses RAII to manage dynamic memory for you. When you use a pointer to a vector you no longer have the benefit of not manually managing the resource yourself.
How do I deallocate contents of a vector upon its destruction?
This is why we have smart pointers.
{
std::vector<std::unique_ptr<cls>> vec;
// C++14 will allow std::make_unique
vec.emplace_back(std::unique_ptr<cls>(new cls(5)));
}
When the vector goes out of scope, the destructors of the unique_ptr
s will be called and the memory will be deallocated.
In your case, with the raw pointers, you'd have to delete
whatever you created with new
manually:
// Something along the lines of this.
for (auto&& elem : vec) {
delete elem;
}
Also, where is memory allocated for the vector as well as the contents if I declare vector as:
You're allocating the vector with new
, so it'll be on the heap.
C++ delete vector, objects, free memory
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.
How does std::vector in c++ gets deallocated by default
There are several STL implementations, they diff from each other, but they are similar. Let's take the latest version of GCC's libstdc++ as an example:
The destructor of std::vector
, all the elements in the vector are destroyed via calling std::_Destroy
~vector() _GLIBCXX_NOEXCEPT
{
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator());
_GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC;
}
The vector
has a base class:
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc>
For the memory used in the vector itself, it is destroyed in _M_deallocate
in the base class, which will call the deallocate
at last:
~_Vector_base() _GLIBCXX_NOEXCEPT
{
_M_deallocate(_M_impl._M_start,
_M_impl._M_end_of_storage - _M_impl._M_start);
}
void
deallocate(_Tp* __p, size_type __n __attribute__ ((__unused__)))
{
#if __cpp_sized_deallocation
# define _GLIBCXX_SIZED_DEALLOC(p, n) (p), (n) * sizeof(_Tp)
#else
# define _GLIBCXX_SIZED_DEALLOC(p, n) (p)
#endif
#if __cpp_aligned_new
if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
{
_GLIBCXX_OPERATOR_DELETE(_GLIBCXX_SIZED_DEALLOC(__p, __n),
std::align_val_t(alignof(_Tp)));
return;
}
#endif
_GLIBCXX_OPERATOR_DELETE(_GLIBCXX_SIZED_DEALLOC(__p, __n));
}
_GLIBCXX_OPERATOR_DELETE
is a macro, we can regard it as delete
fully deallocating the memory of a std::vector container
Yes, it is correct, provided mvMyObjectVector_ptr
has been allocated using new
.
Additionally, MyObject
needs to satisfy certain requirements before it can be used with std::vector
.
The call to clear()
is redundant and can be omitted.
Some likely reasons for the SIGABRT
include:
mvMyObjectVector_ptr
hasn't been allocated usingnew
;MyObject
violates the Rule of Three;- the class the contains the vector violates the Rule of Three.
How to correctly deallocate or delete a c++ vector?
The only way to really get rid off unused memory in a std::vector<>
pre C++11 is to swap it with an empty vector: vector<int>().swap(myvec)
. In C++11 you have a member function shrink_to_fit
which often is implemented as the swap idiom just mentioned.
How to remove object from a vector if it was deleted
From your sample code, I assume your vector is defined somewhat like this:
std::vector<YourType*> entities;
Therefore, your vector does not contain YourType
objects, but pointer to YourType
. That is, the elements the vector manages are the pointers, not the pointed objects.
Thus when you do this delete entities[x + y * width];
you indeed delete the YourType
instance, but the pointer still exists and it sill in your vector.
It might be easier to visualize if you decompose that statement to the equivalent 2 lines:
YourType * pointer = entities[x + y * width];
delete pointer;
To actually remove the pointer from the vector, you need to say so:
entities.erase(entities.begin() + x + y * width);
This would remove the pointer from the array (also shifting all things past that index). You still need to do the delete
yourself as, again, the vector is only managing the pointer, not the YourType
.
Note that unless you have a good reason, you should probably not store the pointer in the vector, but the object itsself. That would remove your confusion:
std::vector<YourType> entities;
// deleting a YourType:
entities.erase(entities.begin() + x + y * width);
No delete
or new
anymore, because the object is directly in the vector. So the vector manages it for you instead of just managing the pointer and letting you deal with the pointed object.
Update after question edit:
In your case, you do have a good reason, because you actually store a non-owning pointer. So it might make sense that entities
and projectiles
store pointers, so they actually point at the same objects.
So both vectors will manage their pointers, but you have to think of how the lifecycle of those two pointers (the one from entities and the one from projectiles) interact with the object itself.
Deleting the object will not get rid of the pointers, in neither of the arrays.
How to properly clean up elements from vectors of object pointers
you mentioned in the comments that the objects will have other pointers to them. this sounds like std::shared_ptr<A>
to me. this way you can have other pointers to your A
objects without memory leaking issues. (std::shared_ptr
comes with a small(!) performance cost, but you should not worry about it for now).
additionally i changed your passage to delete/erase your element from the vector. be aware that the A
objects are still alive IF there are other instances keeping a std::shared_ptr<A>
copy to it (but thats a good thing).
here is the code:
#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>
class A
{
public:
A(int i) { x = i; }
int x;
};
int main()
{
std::vector<std::shared_ptr<A>> Vec;
Vec.emplace_back(std::make_shared<A>(5));
Vec.emplace_back(std::make_shared<A>(4));
Vec.emplace_back(std::make_shared<A>(3));
std::cout << "Size before = " << Vec.size() << std::endl;
Vec.erase(
std::remove_if(std::begin(Vec),std::end(Vec), [](auto&& ptr){ return ptr->x == 3;}),
std::end(Vec));
std::cout << "Size after = " << Vec.size() << std::endl;
for (auto&& a : Vec)
{
std::cout << a->x << std::endl;
}
return 0;
}
Related Topics
Why Aren't Copy Constructors "Chained" Like Default Constructors and Destructors
Friend Declaration Declares a Non-Template Function
Why Do Some People Prefer "T Const&" Over "Const T&"
Passing Reference to Stl Vector Over Dll Boundary
Platform-Independent Guid Generation in C++
How to Have Polymorphic Containers with Value Semantics in C++
Eclipse Cdt: Unresolved Inclusion of Stl Header
How to Compile Openssl for X64
What's the Time Complexity of Iterating Through a Std::Set/Std::Map
C++ Implicit Conversion (Signed + Unsigned)
Pointing to a Function That Is a Class Member - Glfw Setkeycallback
Garbage Collection Libraries in C++
Dependent Scope and Nested Templates
Using 'Const' in Class's Functions
Visual Studio: Link:Fatal Error Lnk1181: Cannot Open Input File