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

问题描述 投票:25回答:5

我正在使用Visual Studio 2008。

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

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

将在没有边界检查operator []的情况下编译释放模式,因此性能不会降低。

我开始考虑这个问题,因为我正在将使用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隐藏的错误)。

c++ visual-studio-2008 bounds-checker
5个回答
28
投票

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

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

他们目前在VS2010中的计划是在发布版本中默认禁用边界检查,但在调试时保持打开状态。 (该宏也被重命名为_ITERATOR_DEBUG_LEVEL。我不知道是否有任何正式文件可用,但它已被提及herehere


12
投票

启用标志_GLIBCXX_DEBUG以对STL容器执行边界检查,如下所述:http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html


4
投票

我过早地问过这个问题,但无论如何我都会发布答案,所以我分享了一些知识。

在调试模式下编译时,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));
        }

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


0
投票

我现在无法访问任何Windows机器。但是如果我在我的mac os x机器上查看用g ++提供的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); }

在DEBUG模式下没有执行检查,事件。此代码中未检出_GLIBCXX_DEBUG宏。

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


-4
投票

C ++将vector operator []定义为不为了速度而抛出异常。

我建议你在Debug Configuration中测试应用程序一段时间,直到你对主要的“隐藏”错误消失有信心。

© www.soinside.com 2019 - 2024. All rights reserved.