为什么std::string在初始值被破坏后仍然有效



std::string损坏的示例导致其值的作用域结束:

#include <bits/stdc++.h>
const int StackSize = 2137;
char stack[StackSize];
template <typename Type>
Type& push(Type value) {
char *ptr = (char*)&value;
std::copy_n(ptr, sizeof(Type), stack);
return *(Type*)stack;
}
template <typename Type>
Type& create(Type value) {
auto &var = push<Type>(value);
std::cout << "Should Be: " << var << 'n';
return var;
}
int main() {
auto &x = create<std::string>("Hello");
std::cout << "Is: " << x << 'n';
}

当我更改函数push以接收指针时,输出是正确的,但目前是"b">

我知道std::string有一个指向c字符串的指针,输出是不同的,因为函数push的参数在作用域结束时会被破坏。

但是为什么当我把指针传给push时,输出仍然是正确的呢?c字符串应在创建结束后销毁。

因为您正试图通过类似C的memcpy/copy_n将非平凡对象(std::string(存储在字符缓冲区中。

显然,这是失败的,因为你只是在那里逐字节地复制它,所以它的数据指针指向与临时value字符串相同的位置,然后,当value析构函数释放数据时(至少如果你的编译器不执行SSO(,你调用UB试图通过堆栈访问它。

我不清楚为您"工作"的代码看起来如何,但我想它只是通过在堆上分配字符串而不删除它来避免问题。

考虑一下在C++(即placement new(中是如何实现的。

相关内容

  • 没有找到相关文章

最新更新