为什么删除堆栈指针是错误的?

时间:2016-07-12 03:05:03

标签: c++ stack delete-operator

我已阅读主题Calling delete on variable allocated on the stack 我知道在堆栈中使用operator delete时,请参阅错误。但我想了解更多更深入的信息。为什么错误?

3 个答案:

答案 0 :(得分:1)

堆栈创建的对象是自动,而非堆栈创建的对象(使用关键字new)是动态,需要使用关键字{{回收1}}。

堆栈上的对象由系统自动使用不同机制回收到使用关键字delete动态分配的对象。

因此,使用关键字new调用未使用动态分配的对象地址的关键字delete一定会造成麻烦。

答案 1 :(得分:1)

在C ++运行时库中埋藏(不是很深)是一种称为堆的数据结构。堆的工作(概念上,无论如何)是从一个巨大的字节数组开始,并在程序要求时将该数组的块发送到程序中。这样你就不必自己实现任何块管理代码(这很好,因为在所有情况下正确有效地处理它都是一项非常重要的编码任务)。

每当你的程序调用{​​{1}}运算符时,调用堆的代码就会切掉该数组的一部分(再次,从概念上讲)并将其交给你的程序使用。相反,当您稍后调用new运算符时,该子字节数组将被返回到堆中,其中堆的代码可以将其与大数组的相邻部分(如果其中一个或两个)合并回来。也可以使用相邻部分)或者至少保留其可用性的记录,以便以后通过delete的调用重新使用。

然而,堆栈上的对象不在堆的巨型数组中;而是他们位于堆栈上。因此,当您在堆栈对象上调用new时,您正在向堆中移动一段内存,该内存从未成为其资源池的一部分。 C ++语言设计者可能要求每个堆实现必须检查这种情况并做一些可预测的响应(例如,忽略未知指针,打印错误消息,或触发断言失败并终止程序),但是每个delete的检查都是低效的,C ++语言优先考虑在运行时尽可能保持高效。因此,将指针传递给先前未由delete返回的delete会调用未定义的行为,这意味着C ++运行时库的设计者不必关心他的内容堆代码将在那种情况下执行,因为这种情况不应该首先发生 - 只有在编写错误时才会发生。所以,不要犯这个错误,因为它会导致你的程序以你不想要的方式运行。

答案 2 :(得分:0)

要正确理解它,首先应该了解堆栈是什么以及堆是什么意思。浏览this以了解进程内存的对齐方式。

当您调用函数时,它会从进程的虚拟内存中接收连续的内存块。它用于接收参数,定义局部变量和存储返回地址等。一旦函数完成执行并返回,就释放该内存。这称为堆栈。

在运行时完成堆分配的位置。因此不保证是连续的。 new函数调用从空闲池中为您找到合适的内存块,delete将其返回到空闲内存池。

由于堆栈和堆在物理上是不同的实体,因此堆上定义的操作不应该在堆栈上执行,因为这会在运行时导致未定义的行为,如 Jeremy Friesner 所述。作为一个拇指规则,最好尽早报告错误,这是编译器在找到堆栈上的对象定义时调用删除时所做的事情。