不能直接将std::string转为const void*,因为&str取的是对象地址而非字符串内容地址;应使用c_str()(适合c字符串)或data()+size()(适合二进制数据),避免reinterpret_cast强转整个对象。

为什么不能直接把 std::string 转成 const void*
因为 std::string 是对象,不是原始内存块;const void* 是裸指针,只认地址和长度。直接取 &str 得到的是 std::string 对象本身的地址(比如指向其内部结构),不是字符串内容的地址——这会导致传给 C 接口时读错数据甚至崩溃。
c_str() 是最常用且安全的做法
它返回 const char*,而 C++ 允许隐式转成 const void*,编译器会自动处理:
std::string s = "hello"; const void* ptr = s.c_str(); // ✅ 正确
-
c_str()保证以'\0'结尾,适合传给write()、send()、memcpy()等 C 函数 - 只要
s不被修改或析构,ptr就有效 - 注意:如果后续调用
s.append()或s.clear(),ptr可能失效(内部缓冲重分配)
需要二进制数据(含 '\0' 字节)时用 data() + size()
当字符串里可能含 '<p>当字符串里可能含 <code>'\0'(比如序列化后的 protobuf 数据),c_str() 会在第一个 '\0' 截断,必须用 data():
c_str() 会在第一个 '<p>当字符串里可能含 <code>'\0'(比如序列化后的 protobuf 数据),c_str() 会在第一个 '\0' 截断,必须用 data():' 截断,必须用 data():
std::string bin = {'a', '\0', 'b', '\xff'};
const void* ptr = bin.data(); // ✅ 返回首字节地址
size_t len = bin.size(); // ✅ 必须同时传长度
-
data()在 C++11 后也保证以'\0'结尾,但语义上它只是“首字节地址”,不承诺可当 C 字符串用 - 传给需要长度参数的函数(如
send(fd, ptr, len, 0))时,data()更准确 - C++20 前,
data()返回类型是const char*,仍可隐式转const void*
别用 reinterpret_cast 强转整个对象
下面这种写法是错的:
const void* ptr = reinterpret_cast<const void>(&s); // ❌ 危险</const>
- 得到的是
std::string对象头的地址,不是字符串内容 - 不同 STL 实现布局不同,
sizeof(std::string)可能是 24 或 32 字节,里面还包含指针、大小、容量等字段 - 哪怕你只读前几个字节,也可能读到 size 字段而非字符
真正要传原始字节,就老实用 c_str() 或 data(),别绕开字符串抽象层。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











