sizeof(arr)仅对栈上原生数组有效,函数内传参后退化为指针导致失效;std::array可用sizeof,std::vector和动态数组不可;模板推导是安全获取栈数组长度的唯一方法。

sizeof(arr) 能直接用,但只对栈上数组有效
在函数内部定义的原生数组(比如 int arr[10]),sizeof(arr) 返回的是整个数组占用的字节数,也就是 sizeof(元素类型) * 元素个数。这是最常用也最安全的场景。
常见错误是把数组传给函数后再用 sizeof —— 此时形参退化为指针,sizeof 返回的是指针大小(通常是 4 或 8 字节),完全不是数组长度。
- ✅ 正确:
int arr[5] = {1,2,3,4,5};<br>size_t bytes = sizeof(arr); // 得到 20(假设 int 是 4 字节) - ❌ 错误:
void func(int a[]) {<br> size_t b = sizeof(a); // 这里 a 是 int*,b 通常是 8(64 位系统)<br>} - 传数组进函数时,必须额外传入长度或使用
std::array/std::vector替代原生数组
std::array 的内存大小用 sizeof 同样可靠
std::array 是栈上固定大小容器,不涉及堆分配,sizeof 能准确返回其总字节数,且支持类型推导和成员函数 .size()。
它和原生数组行为接近,但更安全、可传递、可拷贝 —— 如果你本就想用固定大小数组,优先选它。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
std::array<int> a;</int>→sizeof(a)等于100 * sizeof(int) - 注意:不要和
std::vector混淆 ——sizeof(std::vector<T>)只返回控制块大小(通常 24 字节),不含实际元素内存 - 若需运行时确定大小,必须用
a.size() * sizeof(typename decltype(a)::value_type)
std::vector 和动态分配数组不能靠 sizeof 算真实内存
sizeof 对 std::vector 或 new int[n] 返回的只是对象头或指针本身大小,实际数据在堆上,sizeof 完全不感知。
要算真实占用,得手动计算:容量 × 元素大小(对 vector)或显式记录分配长度(对 raw pointer)。
-
std::vector<int> v(1000);</int>→sizeof(v)是常量(如 24),真实内存 ≈v.capacity() * sizeof(int) -
int* p = new int[500];→sizeof(p)是指针大小;真实内存是500 * sizeof(int),你得自己记住 500 -
v.shrink_to_fit()后,v.capacity()可能变小,但sizeof(v)不变
模板函数里怎么安全获取数组长度?
想写一个通用函数自动提取栈上数组长度,只能靠模板推导 —— 利用数组引用参数保留维度信息。
这是绕过“数组退化”的唯一标准做法,也是 std::size()(C++17)底层原理。
- 写法:
template<typename T, size_t N><br>constexpr size_t array_bytes(const T (&)[N]) {<br> return N * sizeof(T);<br>} - 调用
array_bytes(arr)会正确返回字节数,且编译期计算 - 该函数对
std::array不适用(它是类类型,不是内置数组),需另写重载 - 别试图对指针或 vector 用这个模板 —— 编译不过,这是好事,说明你没搞错类型
真正容易被忽略的是:数组是否在当前作用域内以完整类型存在。只要一取地址、一传参、一转成指针,sizeof 就失效。别依赖 IDE 提示或调试器显示的“大小”,那可能是它猜的;以编译器实际行为为准。

















