据我所知,在标准C ++中,每当使用new运算符时,您还必须在某些时候使用delete运算符来防止内存泄漏。这是因为C ++中没有垃圾收集。在.NET中,垃圾收集是自动的,因此无需担心内存管理。我的理解是否正确?感谢。
答案 0 :(得分:19)
对它的长期回答是,每次调用new
,某处,某种程度上,delete
必须被调用,或者其他一些释放函数(取决于内存分配器等)。
但您不需要提供delete
电话:
delete
,所有子代也将自动delete
。如果您不想使用这些技术中的任何一种,为了防止内存泄漏,您可以尝试使用内存检查工具。 Valgrind特别好,虽然它只适用于Linux
至于.NET,是的,使用gcnew
进行分配意味着内存由.NET跟踪,因此没有泄漏。但是,其他资源(如文件句柄等)不由GC管理。
答案 1 :(得分:9)
在idiomatic高级C ++中,永远不会调用删除。
C ++没有与C#中相同的标准垃圾收集器,因此从根本上说,new
和delete
需要配对。但是,C ++中有一些机制可以完全消除{em>显式对现代风格编写的代码的使用{/ 1}}。
首先要注意的是,在C ++中,使用delete
比在C#中使用new
要少得多。这是因为在C#中,每当创建结构,类或数组的实例时都使用new
,但在C ++中,只有在想要动态管理数据元素时才使用new
。 C ++中的大多数数据不需要动态管理,因此可以在不使用new
的情况下创建。 [换句话说,new
在C#中的含义与在C ++中的含义不同。在C ++中,它专门表示动态分配,而在C#中,它用于任何构造。]
其次,每次在C ++中调用new
时,返回值都应直接传递给smart pointer。智能指针将确保在适当的时候自动为您调用new
。
顺便说一下,除非你是一个编写低级库(或学生学习如何做)的大师,否则你永远不应该调用delete
来在C ++中分配一个数组。标准库(以及Boost / TR1)提供了为您分配和管理数组的模板类。
总之,C ++不使用垃圾收集器,但它确实有自己的自动内存管理形式。这两种方法之间存在细微差别,但这两种方法都可以自动释放内存,从而消除了大多数类型的内存泄漏。
这些概念的权威性演示由C ++创建者Bjarne Stroustrup在回答问题时提供:How do I deal with memory leaks?
另见:
答案 2 :(得分:8)
关于operator new的陈述是完全正确的......但它过分简化了C ++语义。
在C ++中,可以在堆栈上或堆上创建对象:
class Foo {};
int main() {
Foo obj1;
Foo* obj2 = new Foo();
delete obj2;
}
在上面的例子中,在堆栈上创建了obj1,并在堆上创建了obj2(使用new)。在显式调用delete之前,不会销毁在堆上创建的对象。但是,堆栈上的对象在超出范围时会自动销毁(即在此示例中返回main()时)。
这使得C ++中的“资源获取是初始化”成语(a.k.a.RAII)成为可能,它比基本的垃圾收集功能强大得多。需要清理的资源(堆内存,套接字,文件,数据库连接等)通常放在基于堆栈的对象中,其析构函数负责清理。
相比之下,Java和C#不允许在堆栈上构造对象,并且不保证收集将会发生,也不保证终结器将运行(我不是C#的人,所以我可能会有点错了)。因此,当你在Java / C#中获得免费的堆内存管理时,你实际上会在这些语言中获得比在C ++中更多的资源清理代码。
答案 3 :(得分:2)
是的,你是对的,在标准的C ++中(在托管的C ++或它依赖的其他变种中)你必须在每个新的后使用删除。在C#,Java和其他垃圾收集语言中,这不是必需的(实际上大多数语言都没有“delete”运算符)。
答案 4 :(得分:1)
“C ++中没有垃圾收集。”
正确。
答案 5 :(得分:1)
您可以通过两种方式使用C ++和.NET:托管或非托管。在托管模式下,.NET的垃圾收集将代表您处理释放内存;在非托管模式下,你接近C ++的正常/标准行为,所以你必须自己掌控你的记忆。
答案 6 :(得分:1)
自动垃圾收集很有用,但您仍然可以获得内存泄漏,如此问题所示:
它在.NET和Java中有所减少,但这并不意味着它允许自动处理错误的编码。
因此,在C ++中,您需要明确地发布您请求的内容,我认为这有时会更好,因为您知道发生了什么。我希望在.NET和Java中,垃圾收集器在调试模式下几乎没有做什么,以帮助确保人们知道他们在做什么。
答案 7 :(得分:0)
纠正你必须担心C ++上的垃圾收集。
而且......有no need to worry about garbage collection on .NET。
只有你有这样的密集和长脚本,你觉得需要优化,你需要关注它。
编辑:asveikau和Pavel Minaev的评论都很棒,谢谢!我过度概括了传递信息。