C++ 可以给新放置指定堆栈对象地址吗?
忽视这种做法的有用性。(当然,尽管现实生活中的例子很受欢迎。) 例如,以下程序为C++ 可以给新放置指定堆栈对象地址吗?,c++,stack,new-operator,heap-memory,placement-new,C++,Stack,New Operator,Heap Memory,Placement New,忽视这种做法的有用性。(当然,尽管现实生活中的例子很受欢迎。) 例如,以下程序为a输出正确的值: #include <iostream> using namespace std; int main() { int a = 11111; int i = 30; int* pi = new (&i) int(); cout << a << " " << endl; } #包括 使用名称空间std; int main()
a
输出正确的值:
#include <iostream>
using namespace std;
int main()
{
int a = 11111;
int i = 30;
int* pi = new (&i) int();
cout << a << " " << endl;
}
#包括
使用名称空间std;
int main()
{
INTA=11111;
int i=30;
int*pi=new(&i)int();
cout是的,使用指向堆栈上某个对象的指针执行placement new完全可以。它将仅使用该特定指针在中构造该对象。placement new实际上并不分配任何内存-您已经提供了该部分。它只执行构造。随后的删除将不起作用通常是delete
——因为您需要做的就是调用对象的析构函数。实际内存由其他东西管理——在本例中是堆栈对象
例如,对于这种简单类型:
struct A {
A(int i)
: i(i)
{
std::cout << "make an A\n";
}
~A() {
std::cout << "delete an A\n";
}
int i;
};
安置新的建筑,而不是分配,所以没有簿记信息可怕
目前,我可以想到一个可能的用例,尽管它(以这种形式)是封装的一个不好的例子:
#include <iostream>
using namespace std;
struct Thing {
Thing (int value) {
cout << "such an awesome " << value << endl;
}
};
union Union {
Union (){}
Thing thing;
};
int main (int, char **) {
Union u;
bool yes;
cin >> yes;
if (yes) {
new (&(u.thing)) Thing(42);
}
return 0;
}
#包括
使用名称空间std;
结构物{
事物(int值){
coutPlacement new在适当的位置构造元素,不分配内存
本例中的“簿记信息”是返回的指针,应该用来销毁放置的对象
由于放置是一个构造,因此没有与放置关联的删除。因此,放置新位置所需的“清理”操作是销毁
“通常的步骤”是
“分配”内存
在适当位置构造元素
做事
销毁元素(与2相反)
“解除分配”内存(与1相反)
(其中内存可以是堆栈内存,它不需要显式分配也不需要释放,而是随堆栈数组或对象来来去去。)
注意:如果将一个对象“放置”到堆栈上相同类型的内存中,应该记住在对象的生命周期结束时会自动销毁
{
X a;
a.~X(); // destroy a
X * b = new (&a) X(); // Place new X
b->~X(); // destroy b
} // double destruction
不,因为您不删除已更新位置的对象,所以可以手动调用其析构函数
struct A {
A() { std::cout << "A()\n"; }
~A() { std::cout << "~A()\n"; }
};
int main()
{
alignas(A) char storage[sizeof(A)];
A *a = new (storage) A;
std::cout << "hi!\n";
a->~A();
std::cout << "bye!\n";
}
在您的例子中,也不需要调用析构函数,因为int
是可平凡地析构函数,这意味着它的析构函数无论如何都是不可操作的
但请注意,不要在仍处于活动状态的对象上调用placement new,因为不仅会破坏其状态,而且还会调用其析构函数两次(手动调用时调用一次,也会在原始对象应该被删除时调用一次,例如在其作用域的末尾).按照这种逻辑,新的位置总是会被破坏/不可能的。你没有做任何分配…@LightnessRacesinOrbit你是什么意思?正是我说的。它的析构函数可能是不可操作的,但如果你调用析构函数并让它超出范围(你无法避免),它会被调用两次.传统上,新位置会出现在char[]
(正如您在回答中所做的那样)中,而不是出现在int
(如问题中的OP所做的那样).@LightnessRacesinOrbit哦,我在我的示例中搜索。注意:添加了,谢谢!当我在最后一行尝试您的示例时,正如您所示。这是一个gcc错误还是代码中隐藏着未定义的行为?
{
X a;
a.~X(); // destroy a
X * b = new (&a) X(); // Place new X
b->~X(); // destroy b
} // double destruction
struct A {
A() { std::cout << "A()\n"; }
~A() { std::cout << "~A()\n"; }
};
int main()
{
alignas(A) char storage[sizeof(A)];
A *a = new (storage) A;
std::cout << "hi!\n";
a->~A();
std::cout << "bye!\n";
}
A()
hi!
~A()
bye!