tags:

views:

84

answers:

3

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?

+6  A: 

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.

GMan
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
@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()`.
GMan
I believe operator[] will assert the value is in range, so you may see more behavior when compiling in debug mode.
Cogwheel - Matthew Orlando
operator[] is sometimes checked in debug mode
Maciej Hehl
@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
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 - Matthew Orlando
+1  A: 

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 checked
  • vector::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.
   */
Stephen
+1  A: 

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.

Jerry Coffin