C ++对象堆栈和堆上的生命周期

时间:2016-12-24 19:52:06

标签: c++ delphi object-lifetime

我正在尝试翻译我用Delphi制作的一些项目;对象一般可以声明为:

//I have the control of the object and I MUST delete it when it's not needed anymore

male := THuman.Create();
try
 // code
finally
 male.Free; (get rid of the object)
end;

阅读Stroustrup关于C ++的书我已经理解(简而言之)他的语言不需要finally块,因为总有解决方法。现在,如果我想创建一个类,我有两种方法:

    创建对象的
  1. THuman male;,当块{... code ...}结束时超出范围

  2. THuman* male = new THuman我可以控制对象的生命并使用delete

  3. 将其销毁

    本书建议使用第一种方法(即使两者都很好),但我来自Delphi背景,我想使用第二种方法(我控制对象)。

    问题。我无法理解C ++对于对象和在线阅读的两种方法之间的区别我更加困惑。如果我说方法1在堆栈上分配内存和堆上的方法2,这是正确的吗?

    在方法2中(我们在堆中)如果我将值NULL分配给对象,是否仍然需要调用删除?

    例如,Delphi只允许在堆上创建实例,Free删除对象(如C ++中的delete)。

3 个答案:

答案 0 :(得分:3)

简短

1-未使用new创建的对象具有自动生存期(如您所说,在堆栈中创建,但这是大多数编译器选择的实现技术),一旦超出范围,它们将自动释放。< / p>

2-使用new创建的对象的生命周期(在堆中创建,再次作为大多数编译器的实现技术)需要由程序员管理。请注意,删除不是将指针设置为NULL,它应该在之前发生。简单的规则是:

  • 每个new必须与一个delete
  • 匹配
  • 每个new[](动态数组的创建)必须只匹配一个delete[]

ps:匹配这里涉及程序运行时中的一对一事件,不一定是代码本身(您可以控制何时何地删除任何 newed 对象)。

答案 1 :(得分:2)

  

如果我说方法1在堆栈上分配内存并在堆上分配方法2,这是正确的吗?

  

在方法2中(我们在堆中)如果我将值NULL赋给对象,是否仍然需要调用删除?

  • 考虑使用smartpointers而不是原始指针。 Smartpointers是处理指针资源并使其更安全使用的对象。 但是,如果您不能使用智能指针,请确保在指针上调用delete以从堆中释放先前分配的内存,然后再将NULL分配给它。否则你会泄露资源。要检查程序内存管理,可以运行valgrind

答案 2 :(得分:2)

  

在方法2中(我们在堆中)如果我将值NULL赋给对象,是否仍然需要调用删除?

如果在调用delete之前执行此操作,则泄漏内存,如果在NULL指针上调用delete,则会出现seg错误(应用程序崩溃)。

最好的方法是使用堆栈对象,但如果你需要管理对象的存在,请使用上面建议的智能指针(unique_ptr,shared_ptr)。

注意:&#34;泄漏记忆&#34;我的意思是这个区域丢失,无法从程序访问,也不能被操作系统释放。