因为数组作为函数参数时自动退化为指针,sizeof得到的是指针大小而非原数组长度。

为什么 sizeof 对函数参数里的数组失效
在函数内部对形参写 sizeof(arr) 得到的几乎总是指针大小(比如 8),而不是数组真实长度。因为 C++ 中,**数组作为函数参数传递时会自动退化为指针**,编译器根本不知道原始数组多长。
常见错误现象:int arr[] = {1,2,3}; void f(int a[]) { cout 输出 8(64 位系统),不是 12。
- 这是语言机制,不是 bug,也和编译器无关
- 哪怕声明成
void f(int a[100]),a仍是int*,sizeof不会检查 100 - 模板推导例外——下一条说
用模板 + 引用捕获真实长度
唯一能“看到”数组长度的地方是模板实参推导过程,前提是把数组以**引用方式传入**。
实操写法:
template<size_t N>
size_t array_size(int (&arr)[N]) {
return N;
}
- 必须用
int (&arr)[N](带括号的引用),不能写int arr[N]或int* arr - 调用时只能传**具名数组变量**,比如
int x[] = {1,2,3}; array_size(x);—— 传new int[5]或函数返回的局部数组都不行 - 支持任意类型:把
int换成T,加个模板参数即可
动态分配数组(new / std::vector)怎么办
根本不存在“未指定长度的动态数组”这种东西——new int[n] 的 n 你一定知道,否则没法分配;而 std::vector 自带 .size()。
立即学习“C++免费学习笔记(深入)”;
-
int* p = new int[42];→ 长度 42 是你写的,得自己记,sizeof(p)没用 -
std::vector<int> v = {1,2,3};→ 直接用v.size(),这是标准且安全的做法 - 如果只有裸指针又没存长度,C++ 里无法可靠反查——别这么干,这是悬空隐患的源头
字符串字面量的特殊情况
sizeof("hello") 确实返回 6(含末尾 \0),但这只适用于**字符串字面量**,且必须在定义它的作用域内直接用 sizeof。
- 写
const char* s = "hello"; sizeof(s)→ 又变成指针大小 - 写
auto s = "hello"; sizeof(s)→ 推导为const char[6],这时才有效 - 这个技巧不能泛化到其他数组,仅因字符串字面量有特殊类型(
const char[N])
C++ 没有运行时数组长度反射,所有“求大小”的操作都依赖编译期已知信息或显式维护的长度变量。最容易被忽略的是:传进函数就丢长度,想靠 sizeof 挽回,基本是在和语言规则硬刚。


















