贝利信息

c++ vector at()和下标区别_c++数组越界检查

日期:2026-01-06 00:00 / 作者:穿越時空
vector::at() 运行时检查越界并抛出异常,operator[] 不检查、行为未定义;应依数据可信度与调试需求选择:不可信输入或需防御性检查时用at(),可信索引的性能敏感循环中用[]。

vector::at() 会做越界检查,operator[] 不会

这是最核心的区别:at() 在运行时检查下标是否在 [0, size()) 范围内,越界则抛出 std::out_of_range 异常;而 operator[] 完全不检查,行为是未定义的(UB)——可能读到垃圾值、崩溃、静默出错,甚至看似正常但埋下隐患。

什么时候该用 at(),什么时候用 []

at() 的典型场景:

operator[] 的典型场景:

at() 的开销和编译器优化能力

at() 的检查无法被编译器完全优化掉,即使你在调用前刚检查过 i ,编译器通常仍会保留第二次比较(因为 at() 是函数调用,有潜在副作用)。对比之下,operator[] 是内联的,零开销。

示例:

std::vector v = {1, 2, 3};
size_t i = 5;
if (i < v.size()) {
    auto x = v.at(i); // 这里仍会执行越界检查 —— 即使前面刚判断过
}

如果真要兼顾安全与性能,更合理的写法是:

if (i < v.size()) {
    auto x = v[i]; // 直接用 [],信任自己的判断
} else {
    throw std::out_of_range("index out of bounds");
}

数组越界检查不能只靠 at()

at() 只对 std::vector 生效,对原生数组(int arr[10])、std::array(默认也不检查)、指针运算(ptr[i])完全无效。C++ 没有全局数组边界检查机制。

真正能覆盖更多越界场景的方案包括:

别以为用了 at() 就高枕无忧——它只是 vector 的一道窄门,门外还有大片未设防的内存区域。