c ++编译器将这种形式的“new”视为堆栈内存吗?

时间:2012-12-21 16:07:32

标签: c++ memory dynamic

  

可能重复:
  Why does the use of ‘new’ cause memory leaks?

我遇到过像这样的小问题

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

它编译好,但在执行时,shell提供以下内容:

a.out(38303) malloc: *** error for object 0x7fff5fbff8cc: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap

,而

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

按预期正常运行。

让我感到困扰的是,第一个案例并没有使用" new"运营商分配内存? 为什么删除它会导致错误?

我已经多次在网上搜索过,但我找不到合适的解释。 谁能告诉我为什么这是错的?谢谢:))

5 个答案:

答案 0 :(得分:11)

问题是您有内存泄漏,并且您正在删除未动态分配的内容。为什么?由于您动态分配int,因此您将其值复制到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

答案 1 :(得分:10)

你可能想写的是:

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

但请注意,如果他看到那段代码,那么他们心智正常的人就不会雇用你。

答案 2 :(得分:3)

delete &i失败,因为您正在尝试delete new未返回的指针。这是未定义的行为。

int i = *new int;

您将新分配的int的值分配给i。指针迷路了。

答案 3 :(得分:3)

  

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

确实如此。但你不要一直指着它。而是将其(未初始化的)值复制到局部变量中,并泄漏分配的内存;你丢失了唯一的内存指针,所以无法删除它。

  

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

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

答案 4 :(得分:1)

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

您的第一行仅设置i。它仍然存在于堆栈中,将其地址传递给delete是违法的。