strlen只能用于以\0结尾的c风格字符串,它从指针开始逐字节扫描至首个\0,若无\0则越界导致未定义行为;正确使用需满足指针非空、内存可读且含\0;替代方案有sizeof(限编译期数组)和std::string::size()。

strlen 只能用于以 \0 结尾的 C 风格字符串
strlen 不是“获取字符数组长度”的通用工具,它实际做的是:从传入指针开始逐字节扫描,直到遇到第一个 \0 字节为止,返回中间的字节数。这意味着如果字符数组没以 \0 结尾,strlen 会越界读取,行为未定义——常见表现是程序崩溃、返回极大随机值,或卡死。
典型错误场景:
- 用
char arr[5] = {'h','e','l','l','o'};初始化后直接调strlen(arr)→ 没\0,危险 - 用
malloc分配内存但忘记手动置零或写\0 - 从二进制数据(如网络包、文件头)中截取一段字节,误当成 C 字符串传给
strlen
正确使用 strlen 的三个前提
必须同时满足以下三点,strlen 的结果才可靠:
- 输入指针非空(否则
strlen(nullptr)是未定义行为) - 指向的内存区域可读,且在有效范围内
- 该内存中存在一个
\0字节,且它出现在你期望的“字符串结束位置”
安全写法示例:
char str[] = "hello"; // 编译器自动加 \0 → strlen 返回 5
char buf[10] = "hi"; // 前3字节为 'h','i','\0',其余为 0 → strlen 返回 2
char s[6] = {'h','e','l','l','o','\0'}; // 手动补 \0 → strlen 返回 5
替代方案:用 sizeof 获取编译期数组长度
如果你真想获取字符数组**声明时的总长度**(包括可能的 <p>如果你真想获取字符数组**声明时的总长度**(包括可能的 <code>\0),而不是运行时字符串内容长度,sizeof 更合适,但它只对栈上声明的数组有效,对指针无效:
sizeof 更合适,但它只对栈上声明的数组有效,对指针无效:-
char arr[10]; sizeof(arr)→ 返回10 -
char *p = new char[10]; sizeof(p)→ 返回指针大小(通常是 8),不是 10 - 常用技巧:
sizeof(arr) / sizeof(arr[0])得到元素个数
注意:这个值和 strlen(arr) 完全不同——前者是数组容量,后者是实际字符串长度(不含 \0)。
C++ 中更推荐用 std::string 而不是 strlen
现代 C++ 几乎不需要手写 strlen。用 std::string 后,长度通过 .size() 或 .length() 直接获得,类型安全、无越界风险、自动管理内存:
std::string s = "hello"; std::cout <p>只有在与 C API 交互(如 <code>fopen</code>、<code>printf</code>)、处理遗留代码或嵌入式受限环境时,才需谨慎使用 <code>strlen</code>。此时务必确认源数据确实是 null-terminated。</p><p>最常被忽略的一点:<code>strlen</code> 返回的是 <code>size_t</code>,不是 <code>int</code>;和有符号整数比较或做算术时容易触发隐式转换问题,比如 <code>if (strlen(s) - 10 > 0)</code> 在 <code>strlen(s) 时会因无符号回绕变成极大正数。</code></p>
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











