C++ 对象在堆栈和堆上的生命周期
C++ objects lifetime on stack and heap
我正在尝试翻译我用 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
块,因为总是有解决方法。现在如果我想创建一个 class 我有两种方法:
THuman male;
对象在其中创建,然后在块 {... code ...}
结束时超出范围
THuman* male = new THuman
我可以控制对象的生命并用delete
摧毁它
书上建议使用第一种方法(即使两者都可以),但我来自 Delphi 背景,我想使用第二种方法(我有对象的控制权)。
问题。我无法理解 C++ 对象的两种方法之间的区别,在线阅读时我更加困惑。如果我说方法1在栈上分配内存,方法2在堆上分配内存是否正确?
在方法2中(我们在堆中)如果我将值NULL
赋给对象,我还需要调用删除吗?
例如 Delphi 只允许在堆上创建实例,而 Free
删除对象(类似于 C++ 中的 delete
)。
Is it correct if I say that method 1 allocates memory on the stack and method 2 on the heap?
- 是
In method 2 (we're in the heap) if I assigned the value NULL to the object, do I still have to call the delete?
- 考虑使用 smartpointers 而不是原始指针。智能指针是处理指针资源并使它们更安全使用的对象。
但是,如果您不能使用智能指针,请确保在向指针分配
NULL
之前调用指针 delete
以从堆中释放先前分配的内存。否则你会泄漏资源。要检查您的程序内存管理,您可以 运行 valgrind
In method 2 (we're in the heap) if I assigned the value NULL to the object, do I still have to call the delete?
如果您在调用 delete 之前执行此操作,则会泄漏内存,如果您在 NULL 指针上调用 delete,则会出现段错误(应用程序崩溃)。
最好的方法是使用堆栈对象,但如果您需要管理对象的存在,请按照上面的建议使用智能指针(unique_ptr、shared_ptr)。
注意:"Leaked memory" 我的意思是这个区域丢失了,它不能从程序访问,也不能被 OS 释放。
简而言之
1- 不是用 new
创建的对象具有自动生命周期(如您所说,在堆栈中创建,但这是大多数编译器选择的实现技术),一旦超出范围,它们就会自动释放.
2- 使用new
创建的对象(在堆中创建,也是大多数编译器的一种实现技术)的生命周期需要由程序员管理。请注意,删除并不是将指针设置为 NULL,它应该发生在之前。简单的规则是:
- 每个
new
必须与一个唯一的匹配 delete
- 每个
new[]
(动态数组的创建)必须与一个唯一的匹配delete[]
p.s: matched 这里关注的是程序运行时的一对一事件,不一定是代码本身(你可以控制何时何地删除任何 newed 对象)。
我正在尝试翻译我用 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
块,因为总是有解决方法。现在如果我想创建一个 class 我有两种方法:
THuman male;
对象在其中创建,然后在块{... code ...}
结束时超出范围THuman* male = new THuman
我可以控制对象的生命并用delete
摧毁它
书上建议使用第一种方法(即使两者都可以),但我来自 Delphi 背景,我想使用第二种方法(我有对象的控制权)。
问题。我无法理解 C++ 对象的两种方法之间的区别,在线阅读时我更加困惑。如果我说方法1在栈上分配内存,方法2在堆上分配内存是否正确?
在方法2中(我们在堆中)如果我将值NULL
赋给对象,我还需要调用删除吗?
例如 Delphi 只允许在堆上创建实例,而 Free
删除对象(类似于 C++ 中的 delete
)。
Is it correct if I say that method 1 allocates memory on the stack and method 2 on the heap?
- 是
In method 2 (we're in the heap) if I assigned the value NULL to the object, do I still have to call the delete?
- 考虑使用 smartpointers 而不是原始指针。智能指针是处理指针资源并使它们更安全使用的对象。
但是,如果您不能使用智能指针,请确保在向指针分配
NULL
之前调用指针delete
以从堆中释放先前分配的内存。否则你会泄漏资源。要检查您的程序内存管理,您可以 运行 valgrind
In method 2 (we're in the heap) if I assigned the value NULL to the object, do I still have to call the delete?
如果您在调用 delete 之前执行此操作,则会泄漏内存,如果您在 NULL 指针上调用 delete,则会出现段错误(应用程序崩溃)。
最好的方法是使用堆栈对象,但如果您需要管理对象的存在,请按照上面的建议使用智能指针(unique_ptr、shared_ptr)。
注意:"Leaked memory" 我的意思是这个区域丢失了,它不能从程序访问,也不能被 OS 释放。
简而言之
1- 不是用 new
创建的对象具有自动生命周期(如您所说,在堆栈中创建,但这是大多数编译器选择的实现技术),一旦超出范围,它们就会自动释放.
2- 使用new
创建的对象(在堆中创建,也是大多数编译器的一种实现技术)的生命周期需要由程序员管理。请注意,删除并不是将指针设置为 NULL,它应该发生在之前。简单的规则是:
- 每个
new
必须与一个唯一的匹配delete
- 每个
new[]
(动态数组的创建)必须与一个唯一的匹配delete[]
p.s: matched 这里关注的是程序运行时的一对一事件,不一定是代码本身(你可以控制何时何地删除任何 newed 对象)。