自动检查 std::vector 中的边界
Automatically check bounds in std::vector
在使用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
定义的情况下编译代码时,将删除检查。
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中用vector填充一个简单的动态数组
- vector.resize()中的分配错误
- 使用std::vector的OpenCL矩阵乘法
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 在某些循环内使用vector.push_back时出现分段错误
- 当vector是tje全局变量时,c++中vector的内存管理
- std::vector的包装器,使数组的结构看起来像结构的数组
- 为什么(-1)%vector::size()总是返回0
- std::当在256字节边界上写入整数时,流的奇怪行为
- 在C++中将类(带有Vector成员)保存为二进制文件
- 编译器如何区分std::vector的构造函数
- 将 int 数组转换为 std::vector<int*>
- 使用 pqxx 将 std::vector 存储在 postgresql 中,并从数据库中检索它
- 在std::vector上存储带有模板的类实例
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 为什么std::vector比数组慢
- 自动检查 std::vector 中的边界
- 在 dll 边界上公开 std::vector语言 - 编译器独立性的最佳实践
- 使用std::vector和.at()检查2D数组边界