最安全的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 对象且要复用其内存,否则构造即用更干净。