当使用std::list<std::string>时,我偶然发现了堆栈溢出问题std::string的内存泄漏,其中一个注释说:
不要用那么多new。我看不出你为什么在任何地方都用新的。你可以在c++中通过值创建对象,这是使用该语言的一个巨大优势。您不必分配堆上的所有内容。不要像Java程序员那样思考。
我不太确定他这么说是什么意思。
为什么在c++中应该尽可能多地根据值创建对象,这在内部有什么不同?我误解了答案吗?
当使用std::list<std::string>时,我偶然发现了堆栈溢出问题std::string的内存泄漏,其中一个注释说:
不要用那么多new。我看不出你为什么在任何地方都用新的。你可以在c++中通过值创建对象,这是使用该语言的一个巨大优势。您不必分配堆上的所有内容。不要像Java程序员那样思考。
我不太确定他这么说是什么意思。
为什么在c++中应该尽可能多地根据值创建对象,这在内部有什么不同?我误解了答案吗?
当前回答
我想海报的意思是,你不必把所有的东西都分配到堆上,而不是堆栈上。
基本上,对象是在堆栈上分配的(当然,如果对象大小允许的话),因为堆栈分配的成本较低,而不是基于堆的分配,后者涉及分配器的大量工作,并增加了冗长的内容,因为这样您就必须管理分配在堆上的数据。
其他回答
以上所有正确答案还有一点,这取决于你在做什么类型的编程。在Windows中开发内核,例如->堆栈受到严重限制,您可能无法像在用户模式中那样处理页面错误。
在这样的环境中,新的或类似c的API调用是首选的,甚至是必需的。
当然,这只是规则的一个例外。
使用new时,对象被分配到堆中。它通常用于预期扩展时。当你声明一个对象,比如,
Class var;
它被放置在堆栈上。
你总是需要对你用new放在堆上的对象调用destroy。这就有可能导致内存泄漏。放在堆栈上的对象不容易发生内存泄漏!
New在堆上分配对象。否则,对象分配在堆栈上。查一下两者的区别。
避免过度使用堆的一个值得注意的原因是为了性能——特别是涉及c++使用的默认内存管理机制的性能。虽然在简单的情况下分配可以非常快,但是在没有严格顺序的情况下对大小不一致的对象执行大量的新建和删除操作不仅会导致内存碎片,而且还会使分配算法复杂化,并且在某些情况下绝对会破坏性能。
这就是创建内存池要解决的问题,可以减轻传统堆实现的固有缺点,同时仍然允许您在必要时使用堆。
不过,最好还是完全避免这个问题。如果可以将它放到堆栈中,那么就这样做。
许多答案都涉及到各种性能考虑因素。我想解决让OP困惑的评论:
不要像Java程序员那样思考。
事实上,在Java中,正如这个问题的答案所解释的那样,
第一次显式创建对象时使用new关键字。
但在c++中,类型为T的对象是这样创建的:T{}(或T{ctor_argument1,ctor_arg2}对于带参数的构造函数)。这就是为什么通常你没有理由想要使用new。
那么,为什么要用它呢?有两个原因:
您需要创建许多值,这些值的数量在编译时是未知的。 由于c++实现在普通机器上的限制-通过分配太多空间来防止堆栈溢出,以常规方式创建值。
现在,除了你引用的评论暗示的内容之外,你应该注意到,即使是上面的两种情况也已经涵盖得很好了,而不必“求助”使用新的自己:
您可以使用来自标准库的容器类型,它们可以保存运行时可变数量的元素(如std::vector)。 您可以使用智能指针,它为您提供一个类似于new的指针,但确保在“指针”超出作用域的地方释放内存。
因此,在c++社区编码指南中,避免显式的new和delete是一个正式的条款:指南R.11。