应优先使用 asan 检测越界,其次用 std::vector::at() 或自定义 checkedarray;std::array::operator[] 不检查是为零开销,需改用 at()。

用 std::vector::at() 替代 [] 操作符
直接访问裸数组或 std::vector 的 [] 运算符不会做边界检查,越界读写是未定义行为。而 at() 在调试和 Release 模式下(取决于标准库实现)都会检查索引是否在 [0, size()) 范围内,越界时抛出 std::out_of_range 异常。
常见错误现象:用 v[i] 访问 i == v.size() 或负索引,程序崩溃或静默出错,难以定位。
- 仅对
std::vector、std::string、std::deque等容器有效;对裸指针、C 风格数组无效 - 性能开销很小,但不可忽略——每次调用都有一次分支判断,高频循环中慎用
- 必须配合异常处理,否则未捕获的
std::out_of_range会让程序终止
std::vector<int> v = {1, 2, 3};
try {
int x = v.at(5); // 抛出 std::out_of_range
} catch (const std::out_of_range& e) {
// 处理越界
}</int>
编译期加 -fsanitize=address(ASan)
这是目前最实用、开箱即用的越界检测手段,适用于所有内存操作(堆、栈、全局区),不仅能捕获数组越界,还能发现 UAF、use-after-return、缓冲区溢出等。
使用场景:开发/测试阶段快速暴露问题,CI 中集成检测,不建议上线启用(有 2× 左右性能开销 + 内存占用)。
- 仅 GCC/Clang 支持,MSVC 不支持;需链接 ASan 运行时(编译器自动处理)
- 必须关闭优化(
-O0或-O1),否则部分越界可能被优化掉而漏报 - 不能检测所有越界——例如跨多个相邻 malloc 块的“刚好没踩到红区”的越界,ASan 可能放过
g++ -fsanitize=address -O0 -g main.cpp -o main ./main # 运行时触发越界会打印详细报告,含源码行号、内存地址、访问类型
手动封装带检查的数组访问类
当无法使用 std::vector::at()(比如要包装 C 风格数组或固定大小栈数组),又不想依赖 ASan 时,可写一个轻量 wrapper,把检查逻辑集中管理。
关键点在于:检查必须发生在每次访问前,且不能被编译器优化掉(尤其 Release 模式下)。
- 用
[[nodiscard]]提示返回值不应被忽略,避免误用 - 模板参数
N必须是编译期常量,才能做static_assert和生成无分支代码 - 不要用宏封装——宏无法参与类型推导,且调试信息丢失
template <typename t size_t n>
class CheckedArray {
T data[N];
public:
T& at(size_t i) {
if (i >= N) throw std::out_of_range("index out of bounds");
return data[i];
}
const T& at(size_t i) const {
if (i >= N) throw std::out_of_range("index out of bounds");
return data[i];
}
};</typename>
为什么 std::array::operator[] 不检查?
因为 std::array 的设计目标是零开销抽象——它必须和 C 风格数组具有相同的内存布局和性能特征。[] 不检查是标准强制要求,不是疏忽。
容易被忽略的地方:有人以为用了 std::array 就“更安全”,其实只要用 [],它和 int arr[10]; arr[15] = 42; 一样危险。
-
std::array::at()是唯一带检查的成员函数,但它和std::vector::at()一样抛异常 - 静态断言
static_assert(I 只能在编译期对字面量索引起作用,对变量索引完全无效 - 某些 IDE 或静态分析工具(如 clang-tidy 的
cppcoreguidelines-pro-bounds-array-to-pointer-decay)能提示潜在越界,但覆盖率有限
ASan 是最值得优先尝试的方案,它不改代码、覆盖广、报错准;而运行时检查(at() 或自定义 wrapper)适合关键路径明确、需要可控错误处理的场景。别指望编译器默认帮你拦住越界——它连警告都未必给。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











