【发布时间】:2017-03-22 12:34:22
【问题描述】:
我了解 placement new 运算符允许在特定/特定内存位置构造对象。所以我尝试了这个;
#include <iostream>
#include <new>
using namespace std;
struct Any {
int x;
string y;
};
int main() {
string mem1[1];
int mem2[5];
Any *p1 = new (mem1) Any;
Any *p2 = new (mem2) Any;
p1->y = "Hello";
//p2->x = 20;
cout << p1->y << endl;
//cout << p2->x;
return 0;
}
我意识到,我可以将一个字符串设置到我预留的位置以恰好容纳 1 个字符串,但我不能对这样的整数做同样的事情;
int mem2[1];
Any *p2 = new (mem2) Any;
p2->x = 20;
我得到一个缓冲区溢出错误,即使它设法向我显示我放置在该位置的值 20;
为什么?
此外,使用上面显示的完整代码,我留出了 2 个不同的内存位置来保存 2 个对象,这使得 p1->y 打印没有任何问题。但是当我减少这个位置时
int mem2[5]; 到5 以下的任何数字,我认为这与我放置字符串并尝试打印字符串的位置无关,我收到分段错误错误。为什么>= 5?是否与可用内存有关?
有没有办法检查使用 placement new 运算符将对象放置在特定内存位置是否成功?
【问题讨论】:
-
在将新的
Any放入string或int的数组中时,您可能会遇到一些严重的内存对齐问题 -
您必须确保
Any对象适合您尝试放入的空间。mem1肯定太小了。另一个问题是字符串的析构函数是在其作用域的末尾调用的,因此您必须在main结束之前恢复mem1。 -
另外,大多数编译器都足够聪明,可以将
x = 20; cout << x;转换为cout << 20;,而不必费心向x写任何东西。所以这不是一个很好的测试它是否有效。 -
Placement new 保证成功,除非构造函数抛出异常或您引发未定义的行为。如果构造函数抛出你可以
catch它,并且未定义的行为不能被定义检测到。 -
@BoPersson 我没有收到任何错误提示
Any对象不适合mem1所以它运行良好。当我将“mem2”减少到低于5的任何数字时,我在尝试打印mem1中的内容时遇到错误。这就是为什么我很困惑!
标签: c++ placement-new