Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vector::clear in C++

Tags:

c++

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?

like image 540
user1738204 Avatar asked Oct 11 '12 13:10

user1738204


2 Answers

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).

like image 159
Luchian Grigore Avatar answered Oct 14 '22 10:10

Luchian Grigore


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.

like image 30
Benj Avatar answered Oct 14 '22 11:10

Benj