堆上的对象什么时候超出范围

时间:2011-12-16 17:55:09

标签: c++ scope

考虑以下计划:

int main() {

    while(...) {
        int* foobar = new int;
    }

    return 0;
}

foobar何时超出范围

我知道在使用new时,属性是在堆上分配的,需要使用delete手动删除,在上面的代码中,它会导致内存泄漏。但是,范围呢?

我认为,一旦while循环终止,它就会超出范围,因为你不再能直接访问它了。例如,在循环终止后,你不能delete

8 个答案:

答案 0 :(得分:13)

这里要小心,foobar是while循环的本地,但堆上的分配没有作用域,只有在你调用delete时才会被破坏。

就编译器而言,变量和分配没有以任何方式链接。实际上,分配发生在运行时,因此编译器甚至都不会看到它。

答案 1 :(得分:9)

foobar是一个局部变量,在块的末尾超出范围。

*foobar是一个具有手动生命周期的动态分配对象。因为它没有作用域生命周期,所以这个问题没有任何意义 - 它不会拥有一个范围,它可以去哪个范围。它的生命周期是手动管理的,对象一直存在,直到你delete

你的问题带有偏见和先入为主的危险。最好以干净的头脑和开放的态度来接近C ++。只有这样,你才能最大限度地欣赏语言的奇迹。


以下是干净开放的方法:考虑 1)存储类(自动,静态,动态),2)对象生存期(作用域,永久性,手动),3)对象语义(值(副本)与引用(别名)),4)RAII和单一责任类。 清除你的想法 a)堆栈/堆,b)指针,c) new / delete ,d) 析构函数/复制构造函数/赋值运算符

答案 2 :(得分:3)

这是一个非常棒的内存泄漏。堆栈上有一个变量,指向堆上分配的内存。当while循环范围结束时,在丢失对它的引用之前,需要删除堆上的内存。或者,如果您不想对内存管理大惊小怪,请始终使用智能指针来拥有堆上的原始内存并让它自行清理。

#include <memory>
int main() {

    while(...) {
        std::unique_ptr<int> foobar = new int;
    } // smart pointer foobar deletes the allocated int each iteration

    return 0;
}

答案 3 :(得分:2)

当程序到达while循环的右括号时,指针(foobar)将超出范围。因此,如果...中的表达式仍然为真,则每次循环执行时内存都会泄漏,因为在截止括号中丢失了已分配对象的句柄。

答案 4 :(得分:1)

这里foobar是占用堆栈内存的int指针。您使用int动态创建的new实例将转到堆。当foobar超出范围时,您将丢失对它的引用,因此您无法删除堆中分配的内存。

最好的解决方案是:

while(--)
{
    int foobar;
}//it goes out of scope here. deleted from stack automatically!!

如果您仍想使用动态分配,请执行以下操作:

while(--)
{
    int* foobar=new int;
    //do your work here!
    delete foobar; //This deletes the heap memory allocated!
    foobar=NULL;   //avoid dangling pointer! :)
}

答案 5 :(得分:0)

由于foobar在循环体中声明,因此在循环的每次迭代结束时都会超出范围。然后重新声明,并且一次又一次地分配新内存,直到循环结束。 foob​​ar指向的实际对象永远不会超出范围。范围不适用于动态分配(又称堆)对象,仅适用于自动(堆栈)对象。

答案 6 :(得分:0)

在循环的每次交互之后,

foobar超出范围。

您分配并分配给foobar的内存正在泄露,因为它仍然在堆上分配,但程序中没有对它的引用。

答案 7 :(得分:-2)

Foobar指针在堆栈上创建,但新的int在堆上创建。在while循环的情况下,每次代码循环时,foobar都会失去范围。新创建的int在堆上持久存在。在每次迭代时,都会创建一个新的int,并重置指针,这意味着指针不再能访问堆上的任何先前的int。

在以前的每一个答案中,甚至在这一个答案中,似乎缺少的是堆落在范围之外。也许,我的术语不正确,但我知道在某些时候堆也被重置了。一旦程序不再运行,或者计算机关闭,它可能会发生,但我知道它发生了。

让我们从不同的角度来看待这个问题。我写了任何数量的程序,泄漏内存。这些年来,我拥有自己的电脑,我很肯定,我已经泄漏了超过2千兆字节的内存。我的电脑只有1千克的内存。因此,如果堆永远不会超出范围,那么我的计算机有一些神奇的记忆。你们其中一个人是否愿意解释堆的确切时间是否超出范围?