std::tr1::array和boost::array的区别

4
我原本以为std::tr1::array与boost::array相同,当访问超出索引范围时会抛出异常。实际上,我查看了头文件,它也是这样的。有人能解释一下为什么下面的代码在gcc版本4.0.1(Apple Inc. build 5465)上导致总线错误,而在gcc 4.1.2上导致段错误吗?
谢谢。
#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;
}

1
我刚刚使用gcc 4.1.2尝试了一下,得到了预期的异常。您确定这是您尝试过的确切代码吗? - Mike Seymour
2个回答

4

可能是你安装的编译器版本存在 bug。在我的系统上(Linux x86-64),GCC 对你的代码执行如下操作:

$ 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

这似乎在所有情况下都有效,尤其值得注意的是,在我的机器上使用GCC 4.1.2时,它能正确运行,而在你的机器上则失败了。你有没有尝试在崩溃点获取堆栈回溯?Valgrind也可能会有所帮助。


0
你正在分配一个由3个元素组成的数组(array<std::string, 3>),但是你试图访问第4个元素(arr.at(3))。boost::array使用断言进行边界检查。我不确定tr1::array,但如果你阅读(草案)C++0x标准,它不要求array::operator[]()在越界索引时抛出异常。因此,我假设你的tr1::array实现类似于boost::array(在调试版本中引发断言,在发布版本中不执行任何操作)。这可以解释你测试代码中的“总线错误”/“段错误”。

2
所有实现它的标准序列容器都需要使用 at 来检查索引并在必要时抛出 out_of_range 异常。boost::array<>::at 也是如此。 - Mike Seymour
好的,我改正了。我不知怎么把operator[]和at()混淆了。 - hkaiser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接