c++内置数组大小必须为编译期常量,禁用变长数组;应使用constexpr、std::array或std::vector替代,注意初始化、容量与大小的区别及安全访问方式。

数组声明时维度必须是编译期常量
你不能写 int n = 5; int arr[n]; —— 这在标准 C++ 里是非法的(即使某些编译器开了 GNU 扩展允许,也别依赖)。C++ 的内置数组大小必须在编译时确定。
常见错误现象:error: variable length array declaration not allowed in C++
- 用字面量或
constexpr变量:constexpr int N = 10; int arr[N]; - 需要运行时大小?改用
std::vector<int></int>,它才是 C++ 里真正“动态数组”的正确选择 - 如果真要栈上固定大小且大小来自参数,只能靠模板推导:
template<size_t n> void foo(int (&arr)[N]) { ... }</size_t>
用 std::array 替代裸数组更安全
裸数组(int arr[5])一传参就退化成指针,丢掉长度信息;std::array 是零开销封装,保留所有类型和尺寸信息,还能用范围 for、.size()、.data()。
使用场景:函数间传递固定大小数据、想避免指针陷阱、配合 STL 算法(比如 std::sort)
立即学习“C++免费学习笔记(深入)”;
- 声明:
std::array<int> arr = {1,2,3,4,5};</int>—— 注意第二模板参数是字面量,不是变量 - 访问元素:支持
arr[0]、arr.at(0)(带越界检查)、arr.front()/arr.back() - 别写
std::array<int></int>:虽然语法合法,但多数操作未定义,实际项目里基本不用空std::array
std::vector 初始化和容量管理容易混淆
写 std::vector<int> v(10);</int> 创建的是含 10 个默认初始化 int(即 0)的 vector;而 std::vector<int> v; v.reserve(10);</int> 只分配内存,v.size() 仍是 0 —— 这俩完全不是一回事。
性能影响:频繁 push_back 不预分配会触发多次内存重分配(摊还 O(1),但有真实开销);过度 reserve 浪费内存
- 已知元素:直接列表初始化
std::vector<int> v = {1,2,3};</int> - 已知大小且需默认值:
std::vector<int> v(1000);</int> - 只预留空间不构造对象:
v.reserve(1000);,之后仍需push_back或resize才有元素 - 清空后想复用内存?用
v.clear();,别用v = {};—— 后者可能释放内存
遍历数组时下标越界是最隐蔽的崩溃源
写 for (int i = 0; i 多跑一次,踩到内存边界外,可能当场 crash,也可能静默错乱——尤其在优化开启后行为更难预测。
兼容性影响:裸数组没有 .size(),std::array 和 std::vector 有,但返回类型是 size_t(无符号),和有符号 int 混用会报警告甚至逻辑翻转
- 首选范围 for:
for (const auto& x : arr) { ... },彻底避开下标 - 必须用下标?统一用
size_t i,并写i ,别用 <code> - 调试时加断言:
assert(i ,尤其在手写循环处理用户输入索引时 - 注意
std::vector::at()抛异常,[]不检查 —— 调试版可用at,发布版靠测试覆盖
越界不是“会不会出问题”,是“什么时候出问题”——它往往躲过单元测试,在特定内存布局或优化等级下才暴露。别心存侥幸。










