即使它在函数堆栈中,我是否必须删除指针?

时间:2016-12-31 21:38:34

标签: c++

总是删除指针,即使它只是在函数调用堆栈中? 当函数堆栈释放时它不会消失吗?

// just Simple class
class CSimple{
  int a;
}

// just simple function having pointer.
void simpleFunc(){  
  CSimple* cSimple = new CSimple();
  cSimple->a = 10;
  //.. do sth
  delete cSimple;  // <<< Always, do I have to delete 'cSimple' to prevent the leak of memory?
}

void main(){
  for( int =0 ; i< 10 ; i++){
     simpleFunc();
  }

}

3 个答案:

答案 0 :(得分:2)

  

什么时候发布功能堆栈?

&#34; CSimple * csimple&#34;当函数返回时消失。

但是,指针与指针之间存在很大差异。

当指针对象被破坏时,指针指向的任何东西都不会发生。这里只有一个,但有两个对象:

  1. 指针。

  2. 它指向的是什么。

  3. 在这种情况下,指针指向使用new创建的动态范围内的对象。

    此对象不会发生任何事情,否则,您将泄漏内存。

    因此,此对象必须为delete d。

    在您理解并完全围绕这个概念完成后,您的下一步将是打开您的C ++书籍到关于std::unique_ptrstd::shared_ptr类的章节,这将关注对你来说,这些讨厌的细节。您应该学习如何使用它们。现代C ++代码很少需要delete的东西;相反,这些智能指针可以完成所有工作。

答案 1 :(得分:1)

在范围退出时(例如,当函数存在或块{...}完成时),在堆栈上创建的所有对象都将被销毁并释放内存。

这适用于您的情况,即。指针将被销毁,指针占用的内存将被释放。指针指向的对象不会被清除。

当您处理多个流路径(if-else梯形图,多个返回语句)和异常时,这是一个常见问题和噩梦。

为了解决这个问题,我们采用了两个主要策略:

  1. RAII
  2. 智能指针(std::unique_ptrboost::scoped_ptr,遗产std::auto_ptr等)。
  3. RAII - 没有学术考虑 - 只是在堆栈上创建对象,如下所示:

    {
       std::string s;
       fancy_object obj;
    }
    

    当我们退出范围时,objs析构函数将被称为duing stack unwinding。编译器为所有流路径确保这一点,并为我们保留正确的解除分配顺序。

    如果需要使用new在堆上分配内存,请使用智能指针。

    int foo()
    {
        std::unique_ptr<Object> o(new Object);
        ... some more code ...
        if( something ) { return -1 }
        ... some more code ...
        if( something_else ) { return -2 }
        else { not yet }
        return 0;
    }
    

    如您所见,我们可以使用3“存在”离开范围。通常情况下,您需要在所有情况下清除记忆,这很容易出现人为错误。

    我们不依赖于在所有3个位置手动清除对象,而是依赖于对堆栈上创建的对象的自动析构函数调用。编译器会搞清楚。当我们离开范围时,将调用std::unique_ptr析构函数,在delete上调用Object

    不要害怕聪明的poiners。它们不是“慢”,“臃肿”或其他废话。智能注入器的设计目的是不增加访问开销,增加额外的安全性。

    非常类似的技术用于锁。查看std::lock_guard课程。

答案 2 :(得分:0)

是的,您必须delete指向的数据。

指针本身位于堆栈中,不需要删除。

但是,您可以将cSimple存储在堆栈中,然后您不必将其删除:

void simpleFunc(){  
  CSimple cSimple; // no new
  cSimple.a = 10; // "." instead of "->"
  //.. do sth
  // no deletion
}