How rigorous is the bounds checking on vectors compared to heap arrays? How exactly is it checking bounds and how does that compare with how a heap array is checked?
3 Answers
A vector
will do bounds checking if you use the at()
function, for example:
std::vector<int> v(5);
v.at(3) = 10;
v.at(5) = 20; // throws an exception, std::out_of_range
However, if you use operator[]
, there is no bounds checking. (And accessing non-existent elements leads to undefined behavior.)
It should be noted, though, that most implementations will have the possibility to include bounds-checking on all iterators, which is discussed in the answers here. By default, VS2008 and below have it on in Debug and Release, VS2010 does only in Debug. gcc requires you define _GLIBCXX_DEBUG
to get checked iterators.
-
so .at() explicitly calls it to do a check and [] leaves it up to compiler implementation? For some reason i was using the [] and it still seemed more ridged than on regular arrays. Well, thanks for the answer. – Faken Jun 16 '10 at 19:47
-
@Fraken: Yes, `operator[]` just needs to return an existing element. If it can't, what happens leaves your program in an undefined state. (It could crash, return garbage, let an implementation debugger kick in, trigger an assert, etc.) The only way to guarantee you get checks is with `at()`. – GManNickG Jun 16 '10 at 19:49
-
I believe operator[] will assert the value is in range, so you may see more behavior when compiling in debug mode. – Cogwheel Jun 16 '10 at 19:50
-
-
1@Cogwheel: `operator[]` is not required to do any sort of checking. The programmer is responsible for making sure the subscript is valid. This allows somebody who knows what they're doing to do very fast array accesses. Since an out-of-range subscript is undefined behavior, the implementation can do whatever it wants, and since `operator[]` isn't actually defined to do no checking the implementation can do some checking. Some do, some don't. – David Thornley Jun 16 '10 at 20:00
-
Right, i was just responding to "For some reason i was using the [] and it still seemed more ridged than on regular arrays" as a possible explanation. – Cogwheel Jun 16 '10 at 20:06
That is going to be implementation defined, the vector contract provides no bound checking guarantees. But, you know one thing for sure, it will be no worse than a heap array.
In my sgi implementation:
vector::operator[]
is not checkedvector::at()
is bound checked
From the header file definition of operator[]
:
/**
* @brief Subscript access to the data contained in the %vector.
* @param n The index of the element for which data should be
* accessed.
* @return Read-only (constant) reference to data.
*
* This operator allows for easy, array-style, data access.
* Note that data access with this operator is unchecked and
* out_of_range lookups are not defined. (For checked lookups
* see at().)
*/
And for vector::at()
:
/**
* @brief Provides access to the data contained in the %vector.
* @param n The index of the element for which data should be
* accessed.
* @return Read/write reference to data.
* @throw std::out_of_range If @a n is an invalid index.
*
* This function provides for safer data access. The parameter
* is first checked that it is in the range of the vector. The
* function throws out_of_range if the check fails.
*/

- 47,994
- 7
- 61
- 70
In a typical implementation, arrays aren't checked at all, regardless of allocation. std::vector
requires bounds checking on at()
. Out of bounds access with operator[]
gives undefined behavior, so it's possible to do bounds checking on it as well, but this is quite unusual.
More importantly, however, I'd advise generally using algorithms that mostly eliminate the concern in the first place. When you do something like: for (i=0; i<N; i++)
, it's pretty easy for N to be the wrong thing. When you use algorithm(x.begin(), x.end(), ...);
it's a lot easier to gain a reasonable degree of certainty that your logic is correct.

- 476,176
- 80
- 629
- 1,111