Compile error or runtime error when index is out of range of vector class?

When I used the vector class, I found that there was no compilation error or runtime error when indexing out of range of the vector. The problem can be shown with the following code

#include <iostream>
#include <vector>

using namespace std;

int main(){

  vector<double> a(10,0.0);
  a[10]=10.0;
  cout<<"a[10]="<<a[10]<<"\n";
  cout<<"size of a is "<<a.size()<<"\n";
  return 0;
}

      

The result of running this code is

a[10]=10
size of a is 10

      

without error message. One more note: a.size()

it still returns 10

, although I can successfully access the a[10]

.

My question is, is there a way to let the program report an error when trying to index from a range of a vector?

+3


source to share


3 answers


This is by design. operator[]

Doesn't validate the argument to offer the best performance . Just like with nude arrays, accessing an element outside of the vector results in undefined behavior .

... although I can successfully access a[10]

...

This is a valid undefined behavior. It is equally acceptable for your code to throw an exception, crash, pass all your tests, but then explode on your client's face to start a nuclear strike, etc.



You can use std::vector::at(index)

for restricted access. It rejects std::out_of_range

if the index is invalid.

Boundary checking without bounds checking does not have to be an all-or-nothing clause: see How to make a std :: vector [] statement a compilation that does bounds checking in DEBUG but not RELEASE and tools such as Valgrind .

+8


source


You will need to use vector::at(index)

or manually check the ranges before accessing the elements with the operator []

.

Not checking ranges when used []

results in undefined behavior, see its definition:

/**
 *  @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().)
 */

      



at()

:

...
* @throw  std::out_of_range  If @a n is an invalid index.
...

      

+2


source


To add to what others have said:

  • While it is possible to define the specific case you specify at compile time, it is relatively difficult and I don't know which C ++ compiler actually does this.

  • If you are using g++

    with it libstdc++

    , you can add the following before your directives #include

    . This will allow you to check execution boundaries (and many other checks on STL containers), even if you use a statement []

    that is not normally checked:

    #define _GLIBCXX_DEBUG 1
    
          

It is recommended to enable # 2 during development / debugging.

+2


source







All Articles