Reputation: 537
Why is this statement:
cout << values[0] << " " << values[1] << " " << values[2] << endl;
Showing
1 2 3
Even though pop back was used to remove the last element from the vector. Shouldn't the values be removed too? Or does the vector resize even though the element is removed?
Here is the sample code:
// This program demonstrates the vector pop_back member function.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> values;
// Store values in the vector.
values.push_back(1); // Last element in values is 1
values.push_back(2); // Now elements in values are 1,2
values.push_back(3); // Now elements in values are 1,2,3
cout << "The size of values is " << values.size() << endl; // values has 3 elements
// Remove a value from the vector.
cout << "Popping a value from the vector...\n";
values.pop_back();
cout << "The size of values is now " << values.size() << endl; // 1 is Removed thus size is 2
cout << values[0] << " " << values[1] << " " << values[2] << endl;
// Now remove another value from the vector.
cout << "Popping a value from the vector...\n";
values.pop_back();
cout << "The size of values is now " << values.size() << endl;
cout << values[0] << " " << values[1] << " " << values[2] << endl;
// Remove the last value from the vector.
cout << "Popping a value from the vector...\n";
values.pop_back();
cout << "The size of values is now " << values.size() << endl;
cout << values[0] << " " << values[1] << " " << values[2] << endl;
return 0;
}
Upvotes: 2
Views: 10607
Reputation: 29
Even though pop back was used to remove the last element from the vector. Shouldn't the values be removed too?
What do you expect the value to be? 0? Garbage?
Or does the vector resize even though the element is removed?
Yes. The destructor for the object is called and the size (which is just the distance between _M_start
and _M_finish
, it's an ad-hoc stack basically) of the vector is reduced by one, as shown in this implementation:
void
pop_back()
{
--this->_M_impl._M_finish;
this->_M_impl.destroy(this->_M_impl._M_finish);
}
destroy
eventually leads to a function that calls the destructor for the object pointed to by the pointer. From there on, you could reason what the value of an object after its lifetime has ended is: but then you'd be wasting your time. There's no point in reasoning once you've reached undefined behavior.
Here's what operator[]
looks like:
reference
operator[](size_type __n)
{ return *(this->_M_impl._M_start + __n); }
You can see why this is bad if _M_start + __n > _M_finish
.
Upvotes: 2
Reputation: 141554
"values" and "elements" are the same thing. pop_back()
removes the last value from the vector, if the vector is not empty.
vector
is designed so that it is the programmer's responsibility to not access out of bounds of the vector. If a vector has 2 elements and you try to access the third element via any method except for at()
, you cause undefined behaviour.
To get bounds checking, use values.at(0)
instead of values[0]
, etc., and include a try
...catch
block to catch the resulting exception.
Upvotes: 8