重新使用已删除的地址分配可以吗?
Is it alright to reuse a deleted address allocation?
假设我有这个代码:
Obj* objects[10];
char* buffers[10];
// ...
buffers[1] = new char[sizeof(Obj)];
objects[1] = new(&buffers[1]) Obj();
// ...
objects[1]->~Obj();
delete[] buffers[1];
在调用 delete
之后重用 buffers[1]
可以吗?
我所说的重用是指再次使用那个地址space作为分配的地址。
我的意思是使用这段代码
objects[2] = new(&buffers[1]) A();
如果你想为一个对象的不同实例重用一个缓冲区,你应该使用 placement new 来初始化这个预分配内存上的对象。
char buffer[<size>];
MyClass *p = new (buffer) MyClass;
p->~MyClass();
p = new (buffer) MyClass;
首先:placement new需要一个指针,而不是指向指针的指针
objects[1] = new(&buffers[1]) Obj(); // Nope
objects[1] = new(buffers[1]) Obj(); // Yes
也就是说,在删除 buffers[1]
指向的内存之后,您需要分配新内存,然后才能使用它来存储对象的另一个实例。
这就是 new[]
和 delete[]
的首要目的:将一块内存标记为 "no longer needed" 或 "in use"。
但是您当然可以重复使用指针 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
如果重用是指将指针 objects[1]
分配给分配的内存,那么是的,您可以重用它。
如果你想问,你可以使用指针指向的内存和你刚刚用 delete[]
释放的内存,那么不,你不能重用它。您只能使用已分配的内存。
Buffers 是一个指针数组。您可以使用 buffers[1] 在其中存储一个新指针。但是在将新的有效指针放入其中之前,您不应该取消引用缓冲区[1]。
我有一种感觉,您想恢复在缓冲区中分配的 space,但要在其中存储另一个 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];
假设我有这个代码:
Obj* objects[10];
char* buffers[10];
// ...
buffers[1] = new char[sizeof(Obj)];
objects[1] = new(&buffers[1]) Obj();
// ...
objects[1]->~Obj();
delete[] buffers[1];
在调用 delete
之后重用 buffers[1]
可以吗?
我所说的重用是指再次使用那个地址space作为分配的地址。
我的意思是使用这段代码
objects[2] = new(&buffers[1]) A();
如果你想为一个对象的不同实例重用一个缓冲区,你应该使用 placement new 来初始化这个预分配内存上的对象。
char buffer[<size>];
MyClass *p = new (buffer) MyClass;
p->~MyClass();
p = new (buffer) MyClass;
首先:placement new需要一个指针,而不是指向指针的指针
objects[1] = new(&buffers[1]) Obj(); // Nope
objects[1] = new(buffers[1]) Obj(); // Yes
也就是说,在删除 buffers[1]
指向的内存之后,您需要分配新内存,然后才能使用它来存储对象的另一个实例。
这就是 new[]
和 delete[]
的首要目的:将一块内存标记为 "no longer needed" 或 "in use"。
但是您当然可以重复使用指针 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
如果重用是指将指针 objects[1]
分配给分配的内存,那么是的,您可以重用它。
如果你想问,你可以使用指针指向的内存和你刚刚用 delete[]
释放的内存,那么不,你不能重用它。您只能使用已分配的内存。
Buffers 是一个指针数组。您可以使用 buffers[1] 在其中存储一个新指针。但是在将新的有效指针放入其中之前,您不应该取消引用缓冲区[1]。
我有一种感觉,您想恢复在缓冲区中分配的 space,但要在其中存储另一个 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];