sizeof计算编译期内存大小,strlen计算运行期C字符串长度,std::string::length()才是安全的内容长度获取方式。

sizeof 计算的是类型或对象的内存字节数
sizeof 是编译期运算符,不关心内容,只看声明时的类型和布局。对数组、指针、类对象都按其在内存中实际占用的字节数返回。
常见误用:对字符指针用 sizeof 期望得到字符串长度——结果往往是 4 或 8(指针本身大小),而非字符串内容长度。
-
char arr[] = "hello"; sizeof(arr)返回 6(含末尾'\0') -
char* p = "hello"; sizeof(p)返回 4 或 8(取决于平台,是指针变量大小) -
sizeof(std::string)返回该类对象自身固定开销(通常 24 或 32 字节),不是字符串内容长度
strlen 只适用于以 '\0' 结尾的 char* 字符串
strlen 是运行期函数,从传入地址开始逐字节扫描,直到遇到第一个 '\0',返回中间字符个数(不含 '\0')。它不检查指针是否合法,也不处理宽字符或非 C 风格字符串。
典型崩溃场景:传入未初始化的指针、无结束符的字符数组、或 std::string::c_str() 后被释放的内存。
立即学习“C++免费学习笔记(深入)”;
-
char s[] = "abc"; strlen(s)返回 3 -
char s[10] = {'a','b'}; strlen(s)行为未定义(s[2]值不确定,可能不是'\0') -
std::string str = "test"; strlen(str.c_str())合法,但应优先用str.length()
std::string 的 length() / size() 才是安全的“字符串长度”
C++ 中真正面向语义的长度获取方式是 std::string::length() 或同义的 size(),它们返回的是字符串中字符的数量,与编码无关(UTF-8 下仍是字节数,但逻辑上代表 Unicode 码点数需另行处理)。
它不依赖 '\0',不扫描内存,时间复杂度 O(1),且自动管理生命周期。
-
std::string s = "café"; s.length()返回 4(即使含 UTF-8 多字节字符) -
s.c_str()返回的指针可传给strlen,但没必要——直接用s.length()更准更快 -
sizeof(s)和strlen(s.c_str())都不该用于获取std::string的内容长度
宽字符和 std::wstring 要用 wcslen 或 wstring::length()
对 wchar_t* 字符串,strlen 完全失效——它只认 char 和 '\0'。必须用 wcslen(对应宽字符版),或更推荐直接使用 std::wstring::length()。
注意:Windows 下 wchar_t 是 2 字节(UTF-16),Linux 多为 4 字节(ISO 10646),wcslen 返回的是 wchar_t 个数,不是 Unicode 码点数(代理对需额外判断)。
-
wchar_t w[] = L"hi"; wcslen(w)返回 2 -
std::wstring ws = L"?"; ws.length()返回 2(UTF-16 代理对),但实际是 1 个 emoji - 跨平台统计真实 Unicode 字符数,需用 ICU、utf8cpp 等库,不能靠
sizeof/strlen/wcslen
最常被忽略的一点:sizeof 和 strlen 解决的是完全不同的问题——前者问“这块内存多大”,后者问“这个 C 字符串有多长”。混用不仅逻辑错,还极易引发越界或静默错误。










