I have some difficulties in understanding the behaviour of the C++ clear function, when applied to a vector.
I tried to compile and run the following function:
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
unsigned int i;
vector<int> myvector;
myvector.push_back (1);
myvector.push_back (2);
myvector.push_back (3);
cout << "myvector contains:";
for (i=0; i<myvector.size(); i++) cout << " " << myvector[i];
myvector.clear();
myvector.push_back (11);
myvector.push_back (12);
cout << "\nmyvector contains:";
for (i=0; i<myvector.size(); i++) cout << " " << myvector[i];
cout << endl;
cout << " entry3 = " << myvector[2]<<endl;
return 0;
}
And this is the output:
myvector contains: 1 2 3
myvector contains: 11 12
entry3 = 3
How is it possible that the information of the third entry of the vector has not been erased when clearing the vector?
From the docs:
All the elements of the vector are dropped: their destructors are called, and then they are removed from the vector container, leaving the container with a size of 0.
Basically you're invoking undefined behavior on myvector[2]
because that item no longer exists. You only pushed 2 elements in the vector after calling clear()
, so only indices 0
and 1
are accessible.
You're unlucky that it didn't crash, because appearing to work can hide bugs. There's no guarantee that the value is erased.
Trying to access the element with .at(2)
instead will result in an exception being thrown (operator[]()
doesn't do any bound-checking, whereas at()
does).
If you attempt to run this code in debug
mode, it's likely it will crash with a debug assertion. Referencing past the end of an array is undefined behaviour.
What's actually happening is that vector has not wiped the memory it was previously using before you ran clear()
. This memory is still present but it's not defined what will happen if you access it. It's up to you to perform bounds checking to avoid running off the end of a vector. You can do this by looping with size()
as a bounds, or by using at()
and catching the out_of_range
exception. I wouldn't particularly recommend this latter approach since it's not a good idea to use exceptions for runtime checks.
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