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(buffer) std::string(std::move(str));