c风格char数组不能用==比较内容,因只比较地址;应使用strcmp或转std::string;需确保以'\0'结尾、长度充足、避免缓冲区溢出、显式初始化清零,并传入长度信息防越界。

char 数组不能直接用 == 比较内容
很多人写 if (arr == "hello"),结果永远不成立——因为这是比较两个指针地址,不是比字符串内容。C++ 里 char[] 是裸数组,没重载 ==,编译器只做地址比较。
- 用
std::strcmp(arr, "hello") == 0(需#include <cstring></cstring>) - 更推荐转成
std::string:std::string(arr) == "hello",安全且可读 - 注意:如果
arr没以'\0'结尾,strcmp会越界读内存,触发未定义行为
声明时长度必须留够 '\0' 空间
写 char buf[5] = "hello"; 看似刚好,实则危险——"hello" 实际占 6 字节(5 字符 + 1 个 '\0'),这里会截断或触发编译警告(取决于编译器和选项)。
- 正确写法:
char buf[6] = "hello";或更稳妥的char buf[] = "hello";(让编译器算) - 用
strcpy复制前,务必确认目标数组足够大:strcpy(buf, src)不检查长度,src 超长就缓冲区溢出 - 替代方案:
strncpy(buf, src, sizeof(buf)-1); buf[sizeof(buf)-1] = '\0';,但要注意它不保证末尾补'\0'(当 src 长度 ≥ size 时)
初始化后内容可能未清零,别假设它是空字符串
局部 char buf[100]; 声明后,内容是随机栈垃圾;即使写了 char buf[100] = {};,也只保证首字节为 '<p>局部 <code>char buf[100]; 声明后,内容是随机栈垃圾;即使写了 char buf[100] = {};,也只保证首字节为 '\0',其余未显式初始化的元素是 0 —— 这看似安全,但若中间某处写入未覆盖到末尾,strlen 仍可能跨过 '\0' 继续扫描。
strlen 仍可能跨过 '<p>局部 <code>char buf[100]; 声明后,内容是随机栈垃圾;即使写了 char buf[100] = {};,也只保证首字节为 '\0',其余未显式初始化的元素是 0 —— 这看似安全,但若中间某处写入未覆盖到末尾,strlen 仍可能跨过 '\0' 继续扫描。' 继续扫描。
- 需要确定为空字符串,就显式清零:
memset(buf, 0, sizeof(buf)); - 或者用
char buf[100] = "";,等价于全 0 初始化 -
strlen(buf)依赖首个'\0',若你中途只改了前几个字符,后面残留旧数据,strlen就会返回错误长度
传参给函数时容易丢长度信息
把 char arr[20] 传给 void foo(char* p),数组长度信息彻底丢失——p 就是个指针,sizeof(p) 是 4 或 8,不是 20。
立即学习“C++免费学习笔记(深入)”;
- 必须额外传长度:
void foo(char* p, size_t len),否则无法安全遍历或校验边界 - 如果函数要修改内容,调用方得确保
p指向可写内存,且长度足够(比如strcat要求目标有足够空间容纳源串+原结尾'\0') - C++17 起可用
std::span<char></char>包裹数组,保留长度,但要注意它不管理生命周期,仍需确保底层内存有效
C 风格字符串操作最麻烦的从来不是语法,而是每个函数都默认信任你传进来的长度和 '\0' 位置——一旦错一点,崩溃、乱码、安全漏洞就跟着来。











