NonCreature0714
NonCreature0714

Reputation: 6014

Aren't vectors protected from going out of bounds?

I saw this question, and noticed a comment which said:

Maybe you go out of bounds on one of the vectors?

I'm not asking about indexing with [] to an element which is out of bounds, which will obviously be out of bounds. And from what I can tell, that's not what the OP did. (I could be totally wrong.) I've not heard of any other cases for going out of bounds with std::vector.

I was taught vectors are protected from going out of bounds when using .push_back(/*data*/). Due to the very high reputation of the commentor, I have little double that the comment comes from a depth of knowledge. The OP in that question uses .push_back(), which, again, I thought was a std::vector member function protected from going out of bounds.

Is there something important I should learn about std::vector in that regard which someone more expert than I in C++ can explain?

Upvotes: 2

Views: 2598

Answers (3)

Toby Speight
Toby Speight

Reputation: 30831

Some vector methods have bounds checking, but not all.

Bounds-checked operations (throw std::out_of_range for invalid indexes):

  • at

Non-checked operations (exhibit undefined behaviour for invalid indexes):

  • operator[]

Any use of an iterator requires that the iterator be valid (or, in some cases, be the 'end' iterator):

  • erase
  • emplace

Some methods require a precondition (and exhibit undefined behaviour if the vector is empty):

  • front
  • back
  • pop_back

Upvotes: 1

Ajay
Ajay

Reputation: 18421

std::vector is made to be used just like an array, hence index operator doesn't have checks for performance reasons. In Debug builds, they may have asserts to find out bugs. But such checks don't exist in Release build. This way compiler can optimize away the function call itself, and put the array access at the call site. Accessing elements out of bounds is undefined behaviour, and one should use vector::at (performance cost!)

push_back may throw a runtime exception (bad_alloc by the default allocator).

Upvotes: 0

MSalters
MSalters

Reputation: 179877

No, they're not that protected. C++ makes it easy to be correct:

std::vector<int> v;
for (int i : v) // cannot go out of bounds

but in general it cannot always prove up front that you're correct:

std::vector<int> v = something();
int i = v[v[0]]; // How would the compiler know if it's legal?

To make this safe regardsless of the contents of v, you can write

int i = v.at(v.at(0)); // might throw at runtime

but this is slower because of the additional runtime check.

Upvotes: 6

Related Questions