最安全的std::string构造方式是使用以'\0'结尾的char数组直接构造,如std::string s(arr);若已知长度则用std::string s(buf, len)更可靠;避免assign或赋值替代构造;处理UTF-8时需注意length返回字节数而非字符数。

直接用 std::string 构造函数转 char 数组最安全
只要 char 数组以 '\0' 结尾,就能无脑构造:
char arr[] = "hello"; std::string s(arr); // 自动识别长度,不包含 '\0'这是最常用也最不容易出错的方式。它内部调用的是
string(const char*) 构造函数,会逐字扫描直到遇到第一个 '\0'。
注意:如果数组没以 '\0' 结尾(比如用 memcpy 填的原始内存),这个构造方式会越界读 —— 这是新手最常踩的坑。
知道长度时用带长度的构造函数更可靠
当你明确知道有效字符数(比如从网络或二进制协议里读来的数据),就别依赖 '\0',改用带长度的构造:
char buf[1024]; int len = recv(sock, buf, sizeof(buf)-1, 0); std::string s(buf, len); // 显式传入长度,不查 '\0'这个构造函数签名是
string(const char*, size_t),完全绕过空字符判断,既快又安全。
- 即使
buf中间含'\0',也不会被截断 - 不会因忘记补
'\0'导致崩溃或信息泄露 - 比先
memcpy到临时缓冲再构造更省内存
别用 string::assign 或 += 替代构造
有人写 s.assign(arr) 或 s = arr,逻辑上没错,但没必要:
-
s = arr底层仍走同个构造逻辑,多一次赋值开销 -
s.assign(arr)在 C++11 前可能触发额外内存分配(取决于实现) - 对空字符串对象,直接构造比先默认构造再赋值少一次初始化
除非你已有非空 string 对象且要复用其内存,否则构造即用更干净。
遇到中文或 UTF-8 字节数组要小心编码
std::string 本身不关心编码,它只是字节容器。如果你的 char 数组是 UTF-8 编码的中文,string 能存、能传、能写文件,但:
立即学习“C++免费学习笔记(深入)”;
-
s.length()返回的是字节数,不是“字符数”(一个汉字通常是 3 字节) - 不能用
s[i]按“第 i 个汉字”取字符,可能切在 UTF-8 中间导致乱码 - 要做子串、查找、大小写转换等操作,得用
std::u8string+ ICU 或第三方库
纯做 IO 或透传时,按字节处理没问题;一旦涉及文本逻辑,就得升维处理编码问题。











