自动检查 std::vector 中的边界

Automatically check bounds in std::vector

本文关键字:边界 vector 检查 std      更新时间:2023-10-16

在使用std::vector的类的积极开发过程中,经常发生索引越界的情况。(有关实际示例,请参阅此代码审查问题。使用 operator[] 时,这会导致未定义的行为。尽管如此,[]语法还是易于阅读的,比编写.at()更方便。

因此,我想使用 [] 运算符编写代码,但同时启用了边界检查。测试代码后,删除边界检查应该非常容易。

我正在考虑以下代码:

util::bound_checked<std::vector<int>> numbers;
numbers.push_back(1);
numbers.push_back(2);
numbers.push_back(3);
numbers.push_back(4);
std::cout << numbers[17] << "n";

对我来说,这个实用程序模板似乎非常简单,我希望它存在。是吗?如果是,以哪个名称?

我认为

不存在这样的东西,但创建起来相当容易:

template <class Container>
struct bound_checked : public Container
{
  using Container::Container;
  auto operator[] (typename Container::size_type i) -> decltype(this->at(i))
  { return this->at(i); }
  auto operator[] (typename Container::size_type i) const -> decltype(this->at(i))
  { return this->at(i); }
};

[现场示例]

请注意,上面实际上使用了一种不鼓励的做法,即从标准容器(不是为其设计的(进行公共继承。我对你的问题的理解是,这个包装器仅用于测试目的,这很好。但是,如果您希望它保留在生产中并且希望非常安全,请使用非公共继承:

template <class Container>
struct bound_checked : private Container
{
  using Container::Container;
  auto operator[] (typename Container::size_type i) -> decltype(this->at(i))
  { return this->at(i); }
  auto operator[] (typename Container::size_type i) const -> decltype(this->at(i))
  { return this->at(i); }
  using Container::begin;
  using Container::end;
  using Container::at;
  using Container::insert;
  // ... you get the idea
};

对我来说,这个实用程序模板似乎非常简单,以至于我会 期望它存在

gcc libstdc++ 有一组调试容器。对于std::vector__gnu_debug::vector调试容器。请参阅文档。

如果你使用GCC(可能是MinGW(,或者Clang和libstdc++(GCC的标准库(,那么#define _GLIBCXX_DEBUG会做你想做的事。

或者更好的是,用标志定义它:-D_GLIBCXX_DEBUG .

或者,还有 _GLIBCXX_ASSERTIONS ,它执行的检查较少,但编译(并且可能运行(更快。

是吗?如果是,以哪个名称?

我很确定它确实存在。如果启用了编译器内部__DEBUG生成宏,许多编译器将std::vector<T>::at()作为std::vector::operator[]()的实现。

因此,我想使用 [] 运算符编写代码,但同时启用了边界检查。测试代码后,删除边界检查应该非常容易。

关于命名,我会说这是调试发布构建。在没有__DEBUG定义的情况下编译代码时,将删除检查。