reinterpret_cast<std::string*> 在 gcc 上导致分段错误但在 clang 上有效

reinterpret_cast<std::string*> cause segmentation fault on gcc but works on clang

gcc和clang版本都是11,这里是示例代码

#include <string>
#include <cstddef>


void store_rvalue_string(std::byte* buffer, std::string&& value) {
    *reinterpret_cast<std::string*>(buffer) = std::move(value);
}


int main() {
    auto buffer = new std::byte[1024];
    std::string str = "hello";
    store_rvalue_string(buffer, std::move(str));
}

这是一个严格的别名违规,因此是 UB。

一个不太正式的答案是,你在一块内存上调用 std::basic_string::operator=,而 string 构造函数一开始就没有被调用过。

我的猜测是,在 Clang 上,内存恰好用零填充,并且用零字节填充的字符串在标准库实现中算作空。

正确的解决方案是使用 placement-new,创建一个 new 对象(通过调用其构造函数):

new(buffer) std::string(std::move(str));