我可以对用新放置分配的指针调用delete吗?
我们可以对分配有placement
new
的指针调用delete
吗?如果没有那为什么?请详细解释一下。
我知道没有放置删除。但我想知道为什么只是删除操作者不能删除内存而不关心指针指向的内存是如何分配的?
delete
正在做两件事:
- 调用 detrucor
- 释放内存
我认为删除没有理由无法在通过放置 new 创建的对象上调用这两个操作中的任何一个。知道原因吗?
Can we call delete
on the pointer which is allocated with the placement new
? If no then why? Please explain in details.
I know that there is no placement delete. But I wonder why just delete opetator can not delete the memory without caring how that memory on which the pointer points is allocated?
delete
is doing two things:
- Calls destrucor
- Frees memory
And I see no reaason for delete not to be able to call either of these two operations on the object which was created by placement new. Any idea about reasons?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您只能对使用
operator new
创建的指针调用delete
。如果您将放置new
与由普通operator new
分配的内存位置一起使用,那么您可以安全地对其使用delete
(前提是您得到类型和指针正确)。但是,您可以在任何内存上使用放置new
,因此您通常会以其他方式管理该内存并手动调用对象的析构函数。例如,在这种复杂且通常不必要的情况下,可以安全地
删除
您使用放置new
的内存,但这只是因为您使用new<分配了它/code> 之前:
但是,这是非法的:
另一种思考方式是
delete
仅 释放之前由正常 < 分配的内存代码>新。通过放置new
,您不必必须使用由普通new
分配的内存,因此有可能没有被分配普通new
、delete
无法处理。You must only call
delete
on pointers that were created withoperator new
. If you use placementnew
with a memory location that was allocated by the normaloperator new
then you may safely usedelete
on it (provided you get the types and pointers right). However, you can use placementnew
on any memory, so you usually will manage that memory some other way and call the object's destructor manually.For instance, in this convoluted and usually unnecessary scenario, it is safe to
delete
the memory you used placementnew
on, but only because you allocated it withnew
before:However, this is illegal:
Another way to think of it is that
delete
only deallocates memory allocated previously by the normalnew
. With placementnew
, you do not have to use memory that was allocated by the normalnew
, so with the possibility of not having been allocated by normalnew
,delete
cannot deal with it.因为每种类型的内存分配都使用一些特定于实现的内存跟踪(通常是用户地址之前的标头块),这使得分配/释放只有在正确配对时才能工作:
new
必须配对与delete
new[]
必须与delete[]
配对(尽管大多数实现可以混合使用new
和>新[]
)malloc
和 Frieds 必须与free
配对CoTaskMemAlloc
与CoTaskMemFree
配对alloca
不配对(堆栈展开会处理它)MyCustomAllocator
与MyCustomFree
配对尝试调用错误的释放器将导致不可预测的行为(现在很可能是段错误或 之后)。因此,对除
new
之外的任何其他内存分配的内存调用delete
都会导致不好的结果。此外,新的放置可以在任何地址上调用,甚至可能不是分配的地址。它可以在位于某个较大对象中间的地址上调用,可以在内存映射区域上调用,也可以在原始虚拟提交区域上调用,一切都可以。在所有这些情况下,delete 都会尝试执行其实现告诉他要做的事情:减去标头大小,将其解释为新标头,将其链接回堆。轰隆隆。
知道如何释放新地址内存的人是你,因为你确切地知道该内存是如何分配的。
delete
只会做它知道的事情,而且可能不是正确的事情。Because each flavour of memory allocation uses some implementation specific tracking of the memory (usually a header block that precedes the user address) and this make the allocation/deallocation to work only when paired up correctly:
new
must pair withdelete
new[]
must pair withdelete[]
(most implementations though forgive mixing thenew
andnew[]
)malloc
and frieds must pair withfree
CoTaskMemAlloc
pairs withCoTaskMemFree
alloca
pairs with nothing (stack unwinding takes care of it)MyCustomAllocator
pairs withMyCustomFree
Attempting to call the wrong deallocator will result in unpredictable behavior( most likely seg fault now or later). Therefore calling
delete
on memory allocated by anything else other thannew
will result in bad things.Furthermore the placement new may be called on any address, may not even be an allocated address. It can be called on an address located in the middle of some larger object, it may be called on a memory mapped region, it may be called on a raw virtual committed region, anything goes.
delete
woul attempt, in all these cases, to do what its implementation tell him to do: subtract the header size, interpret it as anew
header, link it back into the heap. Kaboom.The one that know how to release the memory of a placement new address is you, since you know exactly how was that memory allocated.
delete
will only do what it knows, and it may not be the right thing.不,因为delete不仅调用析构函数,而且还释放内存,但如果您使用placement new,则必须自己使用malloc()或堆栈分配内存。但是,您必须自己调用析构函数。另请参阅 C++ 常见问题解答。
No, since delete not only calls the destructor but also frees the memory, but if you used placement new you must have allocated the memory yourself using malloc() or stack. You do, however, have to call the destructor yourself. Also see the C++ FAQ.
否。没有放置删除表达式。
典型场景:
请注意,放置新运算符确实有一个相应的强制删除运算符准确地说,
void ::operator delete(void* [, size_t]) { }
,一个无操作;如果T
的构造函数抛出异常,就会调用这个函数。No. There is no placement-delete expression.
Typical scenario:
Note that the placement-new operator does have a corresponding delete operator which is mandated to be precisely
void ::operator delete(void* [, size_t]) { }
, a no-op; this is what gets called if the constructor ofT
throws an exception.不,因为新的放置不会分配任何内存。您可以在先前分配的原始内存上使用新的放置。它唯一做的就是调用对象的构造函数。
No, because a placement new doesn't allocate any memory. You use placement new on previously allocated raw memory. The only thing it does is call the constructor of the object.