I tried to google and search an answer to my question, but I couldn't find any valid explanation hence I am posting my question here. Following is my sample code and output:
#include <iostream> #include "vector" using namespace std; typedef struct Node{ int data; Node(){ data = 0; std::cout << "Node created. " << this <<'\n'; } ~Node(){ data = 0; std::cout << "Node destroyed. " << this <<'\n'; } } Node; int main() { std::vector<Node> vec; for(int i = 0; i < 2 ; i++) vec.push_back( *(new Node)); return 0; }
Node created. 0x9e0da10 Node created. 0x9e0da30 Node destroyed. 0x9e0da20 Node destroyed. 0x9e0da40 Node destroyed. 0x9e0da44
Why is there an extra destroy and why are created objects different from destroyed object?
Vectors are assigned memory in blocks of contiguous locations. When the memory allocated for the vector falls short of storing new elements, a new memory block is allocated to vector and all elements are copied from the old location to the new location. This reallocation of elements helps vectors to grow when required.
As mentioned above, std::vector is a templated class that represents dynamic arrays. std::vector typically allocates memory on the heap (unless you override this behavior with your own allocator). The std::vector class abstracts memory management, as it grows and shrinks automatically if elements are added or removed.
So there is no surprise regarding std::vector. It uses 4 bytes to store each 4 byte elements.
So no matter how you create a vector, its element is always allocated on the heap .
vec.push_back( *(new Node));
is an immediate memory leak.
First you dynamically allocate a Node
, then you copy that Node
into the vector. The copy operation is what creates the new object, which is why this
is different.
The original (dynamically allocated) Node
is never deallocated, but the copies are when the destructor of the vector runs (i.e. at the end of the function).
Why three destructor calls instead of two? That's caused by the automatic reallocation of the vector when you push_back
. It moves/copies its elements to a new memory location, destroying the old elements.
Note that normally, when you simply want a vector of n
default-constructed elements, you'd do:
std::vector<Node> vec(2);
This calls Node()
(the default constructor) for elements vec[0]
and vec[1]
, and you don't need a loop (or dynamic allocation).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With