I have this class:
class aa
{
public:
int i = 0;
~aa(){
std::cout << "killin in the name of" << std::endl;
}
};
And I want to make a vector of this class. First I thought o reserving the needed size:
int main()
{
std::vector<aa> vec;
vec.reserve(2);
vec[0] = *(new aa());
vec[1] = *(new aa());
//use the vector
vec.clear();
return 0;
}
But the destructor was not called.
On the other side, when I fill the Vector using push_back
int main()
{
std::vector<aa> vec;
vec.push_back(*(new aa()));
vec.push_back(*(new aa()));
//use the vector
vec.clear();
return 0;
}
I actually get the destructor called.
Why?
A std::vector
already does this memory management for you.
When you use an std::vector
with simple classes like this, you do not need any new
or delete
calls.
Under the hood, reserve
is just making sure that a chunk of memory is preallocated to hold the specified number of member variables.
Under the hood, resize
will actually create n
new objects. You do not need to explictly call new
.
The code *(new aa())
will create a new aa
object on the heap. When you write vec[0] = *(new aa());
it will attempt to copy the contents of your new object to the object that lives in the address vec[0]
. Thus there are 2 distinct objects alive at this point in time ... one object vec[0]
at one place in memory, and one object elsewhere in memory.
What's worse is that you have now called new
and never deleted that object. You thus have a memory leak.
Almost certainly, what you will want one of these scenarios.
Create a vector, and then resize it to have n
elements. Then use those elements:
int main() {
std::vector<aa> vec;
vec.resize(2);
vec[0].i = ...;
vec[1].i = ...;
//use the vector
return 0;
}
push_back
elements when you want to add things
int main() {
std::vector<aa> vec;
vec.push_back(aa()); // Creates a new aa instance and copies into the vector
aa obj;
vec.push_back(obj); // Copies the existing object's data into a new object in the vector.
//use the vector
return 0;
}
The destructor of vector will delete all of the memory appropriately. No need to explicity clear in this example.
There are more advanced ways that you can use vector, but until you understand this code, you probably should just stick to these basics.