我在new
/operator new
上看到一篇文章:
The many faces of operator new in C++
我无法理解下面的例子:
int main(int argc, const char* argv[])
{
char mem[sizeof(int)];
int* iptr2 = new (mem) int;
delete iptr2; // Whoops, segmentation fault!
return 0;
}
这里,int
的内存没有使用new
分配,因此delete
出现segfault。delete
到底不喜欢这里的什么?当用new
初始化一个对象时,是否隐藏了一些delete
寻找的额外结构?
**编辑:**我将从评论中删除几个帮助我更好地了解情况的回复:
1.正如@463035818_is_not_a_number和@HolyBlackCat指出的,mem
是在堆栈上分配的,而delete
试图释放堆上的内存,这是一个非常明显的错误,在大多数架构上应该会导致segfault。
1.如果mem
在堆上分配时没有适当的new
:
我所知道的唯一方法是,比如说,在堆上分配一个int*
,然后将其reinterpret_cast
分配给一个char数组,并给予delete
一个char指针。在我尝试过的几个架构上,它实际上工作正常,但会导致内存泄漏。一般来说,C++标准在这种情况下没有任何保证。因为这样做会对底层体系结构做出约束性假设。
4条答案
按热度按时间a0x5cqrl1#
delete
从堆中删除对象。您的对象在堆栈上,而不在堆上。new
(new T
,不是您使用的placement-new)执行两项操作:分配堆内存(类似于malloc()
),然后执行初始化(对于类,调用构造函数)。Placement-
new
(您使用的)在 existing 内存中执行初始化,它不分配自己的内存。delete
做两件事:调用析构函数(对于类类型),然后释放堆内存(类似于free()
)。由于对象不在堆上,因此
delete
无法删除其内存。没有只调用析构函数的“placement-
delete
“,而是手动调用析构函数:如果你有一个类类型,你可以用
iptr2->MyClass::~MyClass();
来调用析构函数,释放内存就没有必要了,因为堆栈内存在离开当前作用域时会自动释放。还要注意,您忘记了char数组中的
alignas(int)
。1aaf6o9v2#
删除到底不喜欢这里什么?
事实上,它是为一个并非来自真实的
new
的指针调用的。当一个对象用new初始化时,是否隐藏了它所寻找的其他结构?
对于你的C实现来说,这几乎是肯定的,但这是完全不重要的。句号。
delete
仅为指向使用非位置new
运算符创建的对象的指针定义。否则,这是未定义的行为。这是一个重要的区别。“您的C实现”部分是相关的。当然,不同的C++一个编译器或操作系统将产生不会崩溃的代码,而且什么都不做。或者它可能会在你的监视器屏幕上画一张滑稽的脸。或者在你的扬声器上播放你讨厌的曲调。这就是“未定义的行为”的意思。在这种情况下,“未定义的行为”在你的情况下意味着崩溃。nbewdwxp3#
您只能
delete
已通过new
分配的内容。正如本文中所解释的,placement new跳过了分配:
直接调用placement new跳过了对象分配的第一步。我们不向操作系统请求内存。相反,我们告诉它哪里有内存来构造[3]中的对象。下面的代码示例应该澄清这一点:
不能使用
delete
mem
,因为它尚未通过new
分配。mem
具有自动存储持续时间,并在main
返回时释放。在代码中放置new会在已分配的内存中创建一个
int
。如果int
有析构函数,则需要调用析构函数(但不释放内存)。将int
放置在mem
的内存中不会改变mem
在堆栈上分配的事实。实际上,代码中的新位置与代码中的问题并不相关。
具有未定义的行为,就像您的代码具有的那样。
dxxyhpgq4#
有几种口味的
new
和delete
。(非布局)
new
操作符通过调用operator new()
函数来分配内存。delete
操作符通过调用operator delete()
函数来释放内存。它们是一对。(还不明白吗?读this,或者这个)。
new[]
操作符通过调用operator new[]()
函数来分配内存。delete[]
操作符通过调用operator delete[]()
函数来释放内存。它们是不同的一对。放置
new
运算符不分配内存,也不调用任何类似operator new()
的函数。没有对应的delete
运算符或类似operator delete()
的函数。你不能把一种口味的
new
和另一种口味的delete
混合在一起,这是没有意义的,行为也是不确定的。