如何使 std::vector 的 operator[] 编译在 DEBUG 中进行边界检查,但不在 RELEASE 中进行边界检查

StackOverflow https://stackoverflow.com/questions/1290396

我正在使用 Visual Studio 2008。

我知道 std::vector 使用 at() 函数进行边界检查,并且如果您尝试错误地使用运算符 [] 访问某些内容(超出范围),则会出现未定义的行为。

我很好奇是否可以通过边界检查来编译我的程序。这样,当某些内容超出范围时,operator[] 将使用 at() 函数并抛出 std::out_of_range 。

发布模式将在不进行运算符[]边界检查的情况下进行编译,因此性能不会降低。

我开始考虑这个问题是因为我正在将一个使用 Borland C++ 编写的应用程序迁移到 Visual Studio,并且在一小部分代码中我有这个(i=0,j=1):

v[i][j]; //v is a std::vector<std::vector<int> >

向量“v”的大小为 [0][1](因此向量的元素 0 只有一个元素)。我知道这是未定义的行为,但 Borland 在这里返回 0,VS 崩溃了。我更喜欢崩溃而不是返回 0,所以如果我可以通过抛出 std::out_of_range 异常来获得更多“崩溃”,那么迁移将会更快地完成(因此它会暴露 Borland 隐藏的更多错误)。

有帮助吗?

解决方案

Visual Studio 2005 和 2008 已经进行了边界检查 operator[] 默认情况下,在 两个都 调试和发布版本。

控制这种行为的宏是 _SECURE_SCL. 。将其设置为 0 以禁用边界检查。

他们目前在 VS2010 中的计划是在发布版本中默认禁用边界检查,但在调试中保留它。(该宏也被重命名为 _ITERATOR_DEBUG_LEVEL. 。我不知道是否有任何正式文档可用,但已经提到过 这里这里)

其他提示

使能标志_GLIBCXX_DEBUG做边界上STL容器检查,如这里讨论: http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html

我问这个太过早,但我无论如何张贴的答案,所以我分享一些知识。

在Visual Studio中实现的STL已经做界限处于调试模式编译时检查。这可以在<vector>头中可以看出:

reference operator[](size_type _Pos)
        {   // subscript mutable sequence

 #if _HAS_ITERATOR_DEBUGGING
        if (size() <= _Pos)
            {
            _DEBUG_ERROR("vector subscript out of range");
            _SCL_SECURE_OUT_OF_RANGE;
            }
 #endif /* _HAS_ITERATOR_DEBUGGING */
        _SCL_SECURE_VALIDATE_RANGE(_Pos < size());

        return (*(_Myfirst + _Pos));
        }

所以存在边界检查的矢量类。我没有看其他容器,但我相信他们有同样的机制。

我没有获得任何Windows机器现在。但是,如果我看着相克我的Mac OS X的机器上发表++ STL的实现,从/usr/include/c++/4.0.0/bits/stl_vector.h:

  // element access
  /**
   *  @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/write 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().)
   */
  reference
  operator[](size_type __n)
  { return *(begin() + __n); }

没有检查在调试模式下进行的,虽然事件。没有_GLIBCXX_DEBUG marcro在该代码在这里检查。

有与MSVC提供自己的STL实现看看,看看什么做。如果没有检查在任何情况下peformed ......你没有选择,只能在使用().. :-(

C ++定义向量运算符[]作为不求速度的缘故抛出异常。

我建议您可以测试调试配置的应用程序一段时间,直到你获得自信是主要的“隐藏”的错误了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top