有关在c ++

时间:2015-05-20 18:54:18

标签: c++ pointers

我试图准确理解c ++中删除的变量会发生什么。让我们说我有以下内容。

MyObject * obj;

for (int i = 0; i < 100000000; i++){
    obj = someMethodThatReturnsNewMyObject();
    obj->doSomething();
    delete obj;
}

现在,在实例化时,obj是指向MyObject对象的指针。它首先由行obj = someMethodThatReturnsNewMyObject();初始化。然后调用一些方法只是为了好玩,并删除obj。现在我知道什么时候像这样被删除了,它指向的内存空间被清除,指针被设置为什么都没有

但是,当for循环回来时,我重新初始化指针,导致它分配一个新的内存空间,obj然后指向这个新空间。但是,指针本身从内存中移除了。在整个循环中,它只指向我指出的任何指向或指向任何东西(删除时)。

我的问题是:这是什么时候:指针本身,即指针占用的内存空间是什么时候被删除,为什么我不需要删除它,如果我需要删除记忆指向?

6 个答案:

答案 0 :(得分:5)

指针(变量obj)有automatic storage duration - 就像变量i一样。编译器将发出代码以自动为这样的变量分配内存,并在超出范围时释放它;在调用任何析构函数之后。这个内存将在运行时来自堆栈,这使得分配和释放非常快。

顺便说一句,调用delete obj “将指针设置为无指向”。至少如果你的意思是指针被修改。它将继续具有之前的任何值,但该值将不再指向有效的内存位置。

答案 1 :(得分:2)

  

现在我知道什么时候像这样被删除了,它所指向的内存空间被清除了,

语言未指定运行时环境对内存的作用。该语言仅指定使用该内存是未定义的行为。

  

并且指针设置为不指向任何内容。

这是不正确的。指针的值保持不变。它指向的内存不再有效。

  

指针本身何时(即指针占用的内存空间)何时被删除

具体实施。在通常的实现中,当函数返回时,运行时environemnt会回收内存。根据语言,指针的生命周期结束时指针的生命周期结束。在范围结束后使用指针占用的内存是未定义的行为。

如果你有:

MyObject** ptr = NULL:
for (int i = 0; i < 100000000; i++){

    // obj is defined in the scope of the for loop.
    // It's life ends when the for loop ends.
    MyObject* obj = someMethodThatReturnsNewMyObject();

    obj->doSomething();
    delete obj;

    // Make ptr point to the address of obj.
    ptr = &obj;
}

*ptr = NULL;  // This is undefined behavior since ptr
              // points to memory that is not valid any more.

答案 2 :(得分:1)

程序终止时指针本身被删除。您可能不需要删除指针本身,因为您正在重复使用它,并且它在存在期间在内存中占用相同的空间量。然而,指向的内存随着循环的每次迭代而被回收,以避免填满你的记忆。如果您的 for 循环只运行几次,这不会有问题,但是如果您在没有取消分配该空间的情况下进行大量循环,则可以可能填满你的记忆并使你的程序崩溃。

答案 3 :(得分:1)

delete关键字删除指针指向的内存。它不会删除指针本身。

如何取消分配指针取决于它的声明位置。如果您的示例代码在方法/函数中,它将在堆栈上声明,并在方法/函数返回时释放。如果指针是一个全局变量,那么它将终生于你的程序。

答案 4 :(得分:1)

  

它指向的内存空间被清除,指针被设置为指向任何内容

原谅错字,指针改变了。它仍然指向调用delete之前对象的位置。删除后,通过指针使用对象是“坏”。它可能会工作并访问以前的内容。它可能访问总垃圾(如内存重用)。通过指针调用方法很可能会跳转到空间,希望是segfalting而不是重新格式化磁盘。

您确实希望保留指针变量。每次迭代都会使用它。 delete对于释放指针指向的对象中的内存(并运行任何析构函数)非常有用。

答案 5 :(得分:1)

当你这样做时:删除obj

然后,您要将obj指向的内存位置标记为要删除,并将返回给系统。 Its a bit tricky here larger chucks are mmap'dsmaller ones are managed by heap and deleting it will not be reflected in the system unless it is the topmost。如果它不是堆中的最顶层,那么brk / sbrk将不会被移动,并且当您下次询问/分配大小相同或小于标记为要删除的大小时,将重新使用它。算法有点复杂,但这就是要点。

在你的代码中,在第二次迭代中,obj可以指向一个完全不同的块/块。