Why do I need to delete dynamically created items in vector, manually? Why wouldn't they get deleted or its destructor called when vector got deleted?
Normally something like this, but why needed ?
vector<int*> v;
for (vector<int*>::iterator it = v.begin(); it != v.end(); ++it)
{
delete *it;
}
Firstly, you store raw pointers in your vector. These pointers are just pointers. They can point anywhere. They can point to local objects, which cannot be deleted by delete
. And even if they point to dynamically created objects, it doesn't necessarily mean that the user wants them to die with the vector. How is the vector supposed to know all this?
It is a matter of object ownership. Whoever owns the object is responsible for its proper and timely deletion. Ordinary raw pointers do not express ownership. That is why vector can't make any assumptions about whether the objects need to be deleted or not. If you want to tell the vector that it owns its dynamic objects, use corresponding smart pointers.
Secondly, note that your deletion technique is not necessarily safe in the general case. Some standard containers assume that the data you store in them is always valid. When you do delete
on each vector element, the data in the vector becomes "invalidated" (pointers become indeterminate). This is OK with a vector. But doing something like this in a "smarter" container, like std::map
or std::unordered_set
for example, can and will lead to problems. Even if you destroy the container itself immediately afterwards, it is perfectly possible that the container's destruction algorithm might need to analyze (compare, hash etc.) the values of individual elements. And you just killed them all with your cycle.
Smart pointers naturally resolve this matter. But if you have to use a manual delete
for raw pointers stored in a standard container, a better sequence of steps would be this
i
and store it in pointer p
i
from the containerdelete p
In the end you end up with an empty container and delete
d data. Again, your approach will work for simple sequences, like std::vector
or std::list
, but don't do this with ordered or hashed ones.
Because the language has no way of knowing whether you need them to remain alive when you're done. What if you inserted some pointers to stack objects or something like that? Boom.
This, however, can be remedied by using a smart pointer, which will implement an appropriate policy as to automatic destruction. unique_ptr
and shared_ptr
are the most common and useful.
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