sizeof作用于数组返回总字节数,编译期确定;strlen计算以'\0'结尾的char数组字符数,运行时逐字扫描。二者语义不同,易混淆,推荐用std::array和std::string替代。

sizeof 作用于数组时返回整个内存占用
sizeof 是编译期运算符,对数组名求值时得到的是该类型在内存中所占总字节数,包括所有元素和可能的填充。它不关心内容,只看类型定义。
常见错误是误以为 sizeof(arr) 在函数内也能得到数组长度——实际传入函数后,数组退化为指针,sizeof 返回的是指针大小(通常是 8 字节)。
- 全局或局部定义的
int arr[5]:sizeof(arr)是5 * sizeof(int)(通常为 20) - 函数参数写成
void f(int arr[5]):此时arr已是int*,sizeof(arr)返回指针大小 - 想安全获取数组长度,只能在定义作用域内用
sizeof(arr) / sizeof(arr[0]),且必须确保arr确实是数组类型
strlen 只适用于以 '\0' 结尾的 char 数组
strlen 是运行时函数,原型在 中,它从首地址开始逐字节扫描,直到遇到第一个 '\0',返回前面的字符个数(不含 '\0')。它不管内存分配多大,只认内容逻辑。
典型崩溃场景:传入未初始化或未以 '\0' 结尾的 char 数组,strlen 会越界读取,触发未定义行为。
立即学习“C++免费学习笔记(深入)”;
-
char s[] = "hello":strlen(s)返回5,sizeof(s)返回6(含'\0') -
char s[10] = {'h', 'e', 'l', 'l', 'o'}:strlen(s)仍返回5(前五字节后自动补'\0'),但若写成char s[10]; s[0]='h'; ...且没置'\0',strlen行为不可预测 -
strlen对非char*类型(如int*)无意义,编译可能通过但运行出错
std::array 和 std::string 更安全的替代方案
原生数组和 C 风格字符串容易混淆尺寸与长度,现代 C++ 推荐用带尺寸信息的容器。
std::array 在编译期固定大小,.size() 成员函数直接返回元素个数,类型安全,不会退化为指针;std::string 封装了动态长度管理,.length() 或 .size() 返回有效字符数,且内部保证以 '\0' 结尾(C++11 起)。
-
std::array→a; a.size()永远是5,传入函数也不丢失大小信息 -
std::string s = "hello";→s.length()是5,s.capacity()可能更大,但语义清晰分离“当前长度”和“分配容量” - 二者都支持范围 for、迭代器,避免手算下标和长度匹配错误
char[] 初始化方式直接影响 strlen 结果
同一个 char 数组声明,不同初始化语法会导致是否含 '\0',进而让 strlen 返回完全不同结果,而 sizeof 不变。
-
char s1[] = "abc";→ 实际是{'a','b','c','\0'},sizeof=4,strlen=3 -
char s2[] = {'a','b','c'};→ 没有隐式'\0',sizeof=3,strlen会继续往后找,结果不确定 -
char s3[5] = "ab";→ 初始化为{'a','b','\0',0,0},sizeof=5,strlen=2
这种差异极易被忽略,尤其在处理二进制数据或手动构造字符串时,strlen 的依赖隐式 '\0' 特性本身就是脆弱点。









