最安全的是直接用 c_str(),但指针仅在原 string 未被修改且未析构前有效;C++11 起 data() 等价于 c_str();需可写缓冲区时应预分配 string 或用 vector,禁用 const_cast。
c_str() 最安全,但注意生命周期绝大多数场景下,c_str() 是你该用的函数。它返回一个以 \0 结尾的 const char*,能被 C 风格函数(如 printf、open、strlen)直接接受。
关键限制是:返回指针仅在原 std::string 对象**未被修改且未析构前有效**。一旦 string 被赋值、拼接、清空或离开作用域,指针就悬空。
std::string s = "hello";
const char* p = s.c_str(); // 立即使用
printf("%s\n", p); // 安全const char* p = s.c_str();
s += "!"; // s 内存可能重分配 → p 悬空
printf("%s\n", p); // 未定义行为c_str() 结果存为长期指针(比如类成员),除非你确保 string 的生命周期严格长于该指针的使用期data() 在 C++11 后才保证以 \0 结尾,之前不安全C++11 标准起,std::string::data() 的行为和 c_str() 完全一致——都返回指向以 \0 结尾的内部缓冲区的 const char*。但 C++11 之前,data() 不保证结尾有 \0,所以传给 C 函数极可能出错。
s.data() 和 s.c_str() 效果等价,可互换s.data() 返回的指针不能直接用于 strlen 或 printf 等依赖 \0 的函数__cplusplus 宏判断,例如 #if __cplusplus >= 201103L
char*?别强转,用 std::vector 或手动申请c_str() 和 data() 都返回 const char*,强行 const_cast 去掉 const 是未定义行为(尤其 string 使用写时复制或小字符串优化时)。
gethostname),先分配足够空间:std::string s(256, '\0'); // 预分配并初始化为 \0 gethostname(&s[0], s.size()); // C++11 起 &s[0] 等价于 s.data() s.resize(strlen(s.c_str())); // 截断到实际长度
std::vector 显式管理内存:std::vectorbuf(256); gethostname(buf.data(), buf.size()); std::string result(buf.data()); // 构造新 string
char* p = const_cast(s.c_str()); —— 即使编译通过,运行时崩溃风险极高c_str() 和 data() 在所有主流平台(MSVC / GCC / Clang)上行为一致,无需条件编译。真正影响兼容性的往往是字符集本身:
std::wstring(Windows API 常见),它没有 c_str() 返回 char*,而是 c_str() 返回 const wchar_t*;此时需用 WideCharToMultiByte(Windows)或 std::wstring_convert(C++11,已弃用)转码std::string,c_str() 直接可用;但注意某些旧系统 locale 设置可能导致 mbstowcs 等函数失败c_
str() 的字节序列能直接当某种编码处理——它只是字节拷贝,编码语义由你负责真正容易被忽略的是:哪怕用了 c_str(),只要 string 对象在别的线程被修改,或者被 move 走,那个指针就立刻失效。这不是 API 设计缺陷,而是 C++ 值语义和零拷贝权衡下的必然约束。