-3

可能重复:
为什么使用“新”会导致内存泄漏?

我遇到过这样的小问题

int main() {
    int i = *new int;
    delete &i;
    return 0;
}

它编译正常,但在执行时,shell 给出以下内容:

a.out(38303) malloc: 对象 0x7fff5fbff8cc 的 *** 错误: 被释放的指针未被分配
*** 在 malloc_error_break 中设置断点进行调试
中止陷阱

尽管

int main() {
    int *i = new int;
    delete i;
    return 0;
}

按预期正常运行。

困扰我的是,第一种情况不是使用“new”运算符来分配内存吗?为什么删除时会导致错误?

我在网上搜索了好几次,但我找不到合适的解释。谁能告诉我为什么错了?谢谢 :)

4

5 回答 5

11

问题是您有内存泄漏,并且您正在删除未动态分配的内容。为什么?因为您动态分配 anint然后您将其值复制i. 然后,您尝试i通过指向它的指针删除该对象,但i不是动态分配的 - 它的值只是从某个东西初始化的。您丢失了指向实际动态分配的对象的任何指针。

从图表上看,首先你new int,创建一个int具有动态存储持续时间的对象并返回一个指向该 int 的指针:

        _____        ______
Heap:  | int | <--- | int* |
       |_____|      |______|

然后,您取消引用指针,为您提供int对象并将其值复制到int具有自动存储持续时间的对象。在此之后,您从中获得的指针new会丢失,因为您没有将它存储在任何地方。

        _____
Heap:  | int |
       |_____|
        _____
Stack: | int |
       |_____|

然后您获取int具有自动存储持续时间的地址并尝试使用delete它。

        _____
Heap:  | int |
       |_____|
        _____        ______
Stack: | int | <--- | int* | <-- Cannot delete because it was
       |_____|      |______|     not dynamically allocated
于 2012-12-21T16:09:05.877 回答
10

你可能想写的是这样的:

int main() {
    int& i = *new int;   // note the reference type
    delete &i;
    return 0;
}

但是请注意,如果他看到该代码,没有人会雇用您。

于 2012-12-21T16:14:34.237 回答
3

delete &i失败,因为您试图delete指向一个不是由 . 返回的指针new。这是未定义的行为。

int i = *new int;

您正在将新分配的值int分配给i. 指针正在丢失。

于 2012-12-21T16:08:50.223 回答
3

第一种情况不是使用“new”运算符来分配内存吗?

确实如此。但是您不会保留指向它的指针。相反,您将其(未初始化的)值复制到局部变量中,并泄漏分配的内存;您丢失了指向内存的唯一指针,因此无法删除它。

为什么删除时会导致错误?

因为&i指向局部变量i,而不是分配的内存。删除未分配的任何内容都是错误的new,包括局部变量。

于 2012-12-21T16:12:55.880 回答
1
int main() {
    int i = *new int;
    delete &i;
   return 0;
}

您的第一行仅i设置. 它仍然存在于堆栈中,因此将其地址传递给delete.

于 2012-12-21T16:09:37.720 回答