只有原生栈数组可用 sizeof(arr)/sizeof(arr[0]) 求长度;传参后退化为指针、动态数组、STL 容器均不适用,应改用 std::array::size() 等安全接口。

用 sizeof 除以单个元素大小只对原生数组有效
这是最常被误用的点:只有在定义处、且是栈上分配的原生数组(如 int arr[5];),才能用 sizeof(arr) / sizeof(arr[0]) 正确得到长度。一旦数组退化为指针(比如传入函数后),sizeof 就只返回指针大小(通常是 4 或 8 字节),结果完全不可靠。
常见错误场景:
- 把数组作为参数传给函数时,在函数内部用
sizeof计算 —— 结果恒为 1(当sizeof(int*) == sizeof(int))或其它固定小值 - 用
new int[n]动态分配的数组 ——sizeof对指针无效 - 用
std::vector或std::array却仍套用该公式 —— 类型不匹配,编译可能报错
std::array 直接调用 size() 最安全
std::array 是 C++11 引入的栈上固定大小容器,它保留了尺寸信息,且不退化为指针。只要声明时指定了大小(如 std::array),就能无条件使用 size() 成员函数。
示例:
立即学习“C++免费学习笔记(深入)”;
std::arraya = {1, 2, 3, 4}; std::cout << a.size(); // 输出 4,类型安全,编译期可知
注意:std::array 的大小必须是编译期常量,不能是变量(如 int n = 5; std::array 非法)。
动态数组和函数参数中必须显式传长度
C++ 没有运行时数组长度元数据。对 int* p、int arr[](函数形参写法)、new int[n] 这类情况,长度信息只能靠外部维护。
实操建议:
- 函数接口设计时,**始终把长度作为独立参数**,例如
void process(int* data, size_t len) - 用
std::vector替代裸指针数组 —— 它自带size(),且能自动管理内存 - 若必须用裸指针(如对接 C API),确保调用方明确提供长度,不要试图“推导”
模板推导可捕获原生数组长度,但仅限于函数模板
利用函数模板参数推导,可以在编译期获取原生数组长度,适用于工具函数封装,但不能用于普通函数或运行时场景。
示例:
立即学习“C++免费学习笔记(深入)”;
templateconstexpr size_t array_size(T (&)[N]) { return N; } int arr[10]; std::cout << array_size(arr); // 输出 10,编译期计算
关键限制:
- 参数必须是引用形式
T (&)[N],不能是T*或T[] - 无法用于已退化为指针的变量(如函数返回的数组指针)
- 不能用于
std::vector或动态分配数组
C++ 里“数组长度”不是统一概念:原生数组的尺寸是编译期属性,而指针和动态内存根本没有长度字段。最容易忽略的是——哪怕你写了 int a[100];,只要把它传进一个普通函数,它就立刻失去所有尺寸信息,变成一个光秃秃的指针。











