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?
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.
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.
*/
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.