标准C ++中的垃圾收集是否自动?
据我所知,在标准C ++中,无论何时使用new运算符,都必须在某个时刻使用delete运算符来防止内存泄漏。 这是因为在C ++中没有垃圾收集。 在.NET中,垃圾收集是自动的,所以不需要担心内存管理。 我的理解是否正确? 谢谢。
长时间的答案是,每次调用new
,在某个地方,不知何故,必须调用delete
,或者其他一些deallocation函数(取决于内存分配器等)
但是您不需要成为提供delete
呼叫的人:
delete
,并且其所有子对象也将自动delete
。 如果您不想使用这些技术中的任何一种,为了防止内存泄漏,您可以尝试使用内存检查工具。 Valgrind特别好,但它只适用于Linux
至于.NET,是的,使用gcnew
分配意味着内存被.NET跟踪,所以没有泄漏。 但是,其他资源,如文件句柄等不受GC管理。
你关于operator new的陈述是完全正确的......但是它过分简化了C ++语义。
在C ++中,可以在堆栈或堆上创建对象:
class Foo {};
int main() {
Foo obj1;
Foo* obj2 = new Foo();
delete obj2;
}
在上面的例子中,在堆栈上创建obj1,并在堆上创建obj2(使用new)。 在堆上创建的对象不会被销毁,除非明确调用它们。 但是,堆栈中的对象在超出作用域时会自动销毁(即,在此示例中,当main()返回时)。
这使C ++中的“资源获取初始化”成语(又名RAII)成为可能,这比基本的垃圾收集功能强大得多。 需要清理的资源(堆内存,套接字,文件,数据库连接等)通常放在基于堆栈的对象中,这些对象的析构函数负责清理。
相反,Java和C#不允许在堆栈上构建对象,并且不保证集合将会发生,也不会保证终结器将运行(我不是C#人员,所以我可能在这里有点不对) 。 所以,当你在Java / C#中获得免费的堆内存管理时,实际上最终会在这些语言中得到比在C ++中更多的资源清理代码。
在惯用的高级C ++中, 你永远不会调用delete 。
C ++没有一个标准的垃圾回收器,它的工作原理与C#中的相同,因此,从根本上讲, new
和delete
需要配对。 但是,C ++中有一些机制完全消除了用现代风格编写的代码的显式使用delete
。
首先要注意的事情是,在C ++中使用new
更频繁地比你使用new
的C#。 这是因为在C#中,每当创建结构,类或数组的实例时都使用new
,但在C ++中,只有在需要动态管理数据元素时才使用new
。 C ++中的大多数数据不需要动态管理,因此可以在不使用new
情况下创建。 [换句话说,C#中的new
与C ++有不同的含义。 在C ++中,它具体指示动态分配,而在C#中则用于任何构造。]
其次,只要你在C ++中调用new
,返回值应该直接交给一个智能指针。 智能指针将确保在适当的时候自动为您调用delete
。
顺便说一下,除非你是编写低级库的专家(或者学习如何做这件事的学生),否则你绝不应该用new
来调用C ++中的数组。 标准库(以及Boost / TR1)提供了为您分配和管理阵列的模板类。
总之,C ++不使用垃圾回收器,但它有自己的自动内存管理形式。 这两种方法之间存在细微的差异,但两种方法都可以自动释放内存,从而消除大多数类型的内存泄漏。
这些概念的权威性演示由C ++创建者Bjarne Stroustrup在回答这个问题时给出:我如何处理内存泄漏?
也可以看看:
上一篇: Is garbage collection automatic in standard C++?
下一篇: Malloc vs new