Reputation: 6014
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
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
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
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