重用已删除的地址分配是否可以?

时间:2015-05-22 07:22:07

标签: c++ memory placement-new

我们说我有这段代码:

Obj*  objects[10];
char* buffers[10];
// ...
buffers[1] = new char[sizeof(Obj)];
objects[1] = new(&buffers[1]) Obj();
// ...
objects[1]->~Obj();
delete[] buffers[1];

在调用buffers[1]后重用delete是否可以?

重用的意思是再次使用该地址空间作为分配的地址。

我的意思是使用此代码

objects[2] = new(&buffers[1]) A();

4 个答案:

答案 0 :(得分:2)

首先:placement new需要一个指针,而不是指向指针的指针

objects[1] = new(&buffers[1]) Obj(); // Nope
objects[1] = new(buffers[1]) Obj();  // Yes

也就是说,在你删除buffers[1]指向的内存之后,你需要在使用它来存储另一个对象实例之前分配新内存。

这首先是new[]delete[]的目的:将一大块记忆标记为"不再需要"或"正在使用"。

然而,您当然可以重复使用指针buffers[1]指向新的内存位置,但在您发布的代码无效后执行此操作

objects[2] = new(buffers[1]) A();

因为您正在尝试在已删除的内存位置上构建对象。这将触发未定义的行为

这是有效的

Obj*  objects[10];
char* buffers[10];
// ...
buffers[1] = new char[sizeof(Obj)];
objects[1] = new(buffers[1]) Obj();
// ...
objects[1]->~Obj();
delete[] buffers[1];

// Allocate something else and build an object there. Remember that
// 'objects' is an array of pointers to Obj objects
buffers[1] = new char[sizeof(Obj)];
objects[1] = new(buffers[1]) Obj();
// You might now destroy and deallocate

答案 1 :(得分:1)

Buffers是一个指针数组。您可以使用buffers [1]在其中存储新指针。但是,在将新的有效指针放入内部之前,不应该取消引用缓冲区[1]。

我有一种感觉,你想要在缓冲区中分配空间,但是要在其中存储一个其他的Obj。只要不删除使用buffers[1] = new char[sizeof(Obj)];

分配的内存,就可以执行此操作
Obj*  objects[10];
char* buffers[10];
// ...
buffers[1] = new char[sizeof(Obj)];
objects[1] = new(buffers[1]) Obj();
// ...
objects[1]->~Obj();

// you can store a new Obj object in the same place before deleing memory
objects[2] = new(buffers[1]) Obj();
objects[2]->~Obj();
delete[] buffers[1];

但是,您无法在同一位置存储不同类型的对象,因为它们的大小可能不匹配。在这种情况下,你必须释放分配的内存(使用delete []),然后用new重新分配它。

Obj*  objects[10];
char* buffers[10];
// ...
buffers[1] = new char[sizeof(Obj)];
objects[1] = new(buffers[1]) Obj();
// ...
objects[1]->~Obj();    
delete[] buffers[1];

buffers[1] = new char[sizeof(A)];
A* objA = new(buffers[1]) A(); // can't store A in objects[] since its not Obj
objA->~A();
delete[] buffers[1];

答案 2 :(得分:0)

如果要为对象的不同实例重用缓冲区,则应使用placement new来初始化此预分配内存中的对象。

char buffer[<size>];
MyClass *p = new (buffer) MyClass;
p->~MyClass();
p = new (buffer) MyClass;

答案 3 :(得分:0)

如果通过重用意味着将指针objects[1]分配给已分配的内存,那么是的,您可以重用它。

如果您要问,是否可以使用指针指向的内存以及刚刚用delete[]取消分配的内存,那么不能重复使用它。您只能使用已分配的内存。