Differnece between oprator[] and "at" function of vector

What’s the difference between the following statement? Can you predict?

vector<int> vec;
vec.push_back(5);
vec[0] = 10; // Statement A
vec.at(0) = 11; // Statement B

How statement A and B differs?

Basically, both of them are doing same thing. i.e access the members at a specified location.
But vec.at(0) will be more safe than operator[]. If we are accessing out-of-boundary elements of container(vector), it will throw std::out_of_range exception on calling “at” function.
As per the standard specification, operator[] of vector container will not throw any exception if we are accessing out-of-boundary elements.

If you do something as follows, you program will get crashed.

i.e
vector<int> v; // not initialized
v[10] = 10; // Crashes here.
——————————————
vector<int> v; // not initialized
v.at(10) = 10; // safe if we catch the exception

OK. Then why vector provides two functions to do the same thing? Yea! it’s for performance. because “at” function will check the overflow and underflow of the index specified with it’s size. So on each time you calling the function, this checking will happen, which is a performance glitch on some context. Moreover vectors are considered like arrays so it should facilitate element access as fast as arrays do(have you heard any array that do boundary checking?).

int nSize = v.size();
for(int i =0;i<nSize;i++)
cout<<v[i]; // This will be faster than “at” function
In the above code there’s no chance(normal case) of failure so that we can simply access the elements using operator[] which will make the iterations faster
The following code will be ideal in the case of “at” function
try
{
vector<int> v;
v.at(10) = 10;
}
catch(std::out_of_range)
{
cout<<”out of range”;
}
Let me conclude. If you are sure that element is existing there, you can access it by operator[], and if you are unsure call “at” function enclosed within a try catch block

One more thing: The STL vendors can offers exception mechanism with the libraries. So depending on the vendor, operator[] may throw exception. Visual C++ 2005 libraries are secure. If we enable _SECURE_SCL macro(checked iterators), these functions will be throwing exceptions.

You can enable Checked iterators by definining #define _SECURE_SCL 1
To disable
#define _SECURE_SCL 0

Thanks Heb Sutter for your wonderful book called “Exceptional C++”

View CommentsDiffernece between oprator[] and "at" function of vector

  • kd

    nice post.
    what happen if we use like this
    try{ v[1000] = 10; }
    catch(…){}

    v is vector of zero size.
    I still get the exception in this case.

    try{ v[1000] ; } //In this case no exception, i think since we are not accessing thing

    catch(…){}

  • Thanks.
    KD,
    it’s an exception on accessing invalid memory. That’s why it’s getting inside the common catch block. It could be any error, not the bug of vector, suppose if the copy contructor or operator= of the type we are passing to the vector could also throw the exception, or any other function. It can be anything which causes the exception. but it’s not possible for us to catch anything related out of range access of vector.
    As I said in the post, If you are using Visual Studio 2005 and you disabled the checked iterators, the exception will not be caught in the common block. It will simply crash.

    The behavior of the same may differ vendor to vendor and as per the standard there’s no exception specification for operator[]
    HTH

  • [...] what should happen when out of bound access is made? Once you have made up your mind, check out the rational behind the way STL [...]

  • sweet post! I like your writing style.

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

blog comments powered by Disqus