views:

115

answers:

2

I was under the impression that std::tr1::array was the same as the boost::array in that it would throw an exception when accessing an index out of bounds. In fact, I took a peek in the header and it appears that way as well. Could someone explain why the following code results in a bus error (gcc version 4.0.1 (Apple Inc. build 5465)) and a segfault on gcc 4.1.2?

Thanks.

#include <exception>
#include <iostream>
#include <string>
#include <tr1/array>
#include <boost/array.hpp>

int main()
{
    // boost::array<std::string, 3> arr;
    std::tr1::array<std::string, 3> arr;
    try
    {
        arr.at( 0 ) = "one";
        arr.at( 1 ) = "two";
        arr.at( 2 ) = "three";
        arr.at( 3 ) = "nogood";
    }
    catch ( const std::exception& e )
    {
        std::cout << "exception: " << e.what() << std::endl;
    }
    return 0;
}
+3  A: 

It may be a bug in your particular installed version of the compiler. Here's what GCC does for your code on my system (Linux x86-64):

$ g++-4.1.2 test.cpp -o test
$ ./test
exception: array::_M_at
$ g++-4.3.5 test.cpp -o test
$ ./test
exception: array::at
$ g++-4.4.4 test.cpp -o test
$ ./test
exception: array::at
$ g++-4.5.0 test.cpp -o test
$ ./test
exception: array::at

So this seems to work across the board, and it's particularly telling that it seems to work correctly on my machine with GCC 4.1.2 where it fails with yours. Have you tried getting a stack backtrace at the point of the crash? Valgrind also might be helpful.

Jack Lloyd
A: 

You're allocating an array of 3 elements (array<std::string, 3>), but you're trying to access the 4th element (arr.at(3)). boost::array does bounds checking with an assertion. I'm not sure about tr1::array, but if you read the (draft) C++0x Standard, it does not require the array::operator[]() to throw on out of bounds indicies. So I assume your implementation of tr1::array is behaving similarily to boost::array (raising an assertion in debug builds, doing nothing in release builds). This would explain the 'bus error'/'segfault' in your test code.

hkaiser
`at` is required to check the index and throw `out_of_range` if necessary for all standard sequence containers that implement it. `boost::array<>::at` does the same.
Mike Seymour
Ok, I stand corrected. I somehow mixed up operator[] with at().
hkaiser