当使用std::list<std::string>时,我偶然发现了堆栈溢出问题std::string的内存泄漏,其中一个注释说:

不要用那么多new。我看不出你为什么在任何地方都用新的。你可以在c++中通过值创建对象,这是使用该语言的一个巨大优势。您不必分配堆上的所有内容。不要像Java程序员那样思考。

我不太确定他这么说是什么意思。

为什么在c++中应该尽可能多地根据值创建对象,这在内部有什么不同?我误解了答案吗?


当前回答

两个原因:

在这种情况下没有必要。您正在使代码不必要地变得更加复杂。 它在堆上分配空间,这意味着您必须记住稍后删除它,否则将导致内存泄漏。

其他回答

因为堆栈速度更快,而且防漏

在c++中,只需要一条指令就可以为给定函数中的每个局部作用域对象在堆栈上分配空间,而且不可能泄漏任何内存。该评论意图(或应该意图)说“使用堆栈而不是堆”之类的话。

New在堆上分配对象。否则,对象分配在堆栈上。查一下两者的区别。

许多答案都涉及到各种性能考虑因素。我想解决让OP困惑的评论:

不要像Java程序员那样思考。

事实上,在Java中,正如这个问题的答案所解释的那样,

第一次显式创建对象时使用new关键字。

但在c++中,类型为T的对象是这样创建的:T{}(或T{ctor_argument1,ctor_arg2}对于带参数的构造函数)。这就是为什么通常你没有理由想要使用new。

那么,为什么要用它呢?有两个原因:

您需要创建许多值,这些值的数量在编译时是未知的。 由于c++实现在普通机器上的限制-通过分配太多空间来防止堆栈溢出,以常规方式创建值。

现在,除了你引用的评论暗示的内容之外,你应该注意到,即使是上面的两种情况也已经涵盖得很好了,而不必“求助”使用新的自己:

您可以使用来自标准库的容器类型,它们可以保存运行时可变数量的元素(如std::vector)。 您可以使用智能指针,它为您提供一个类似于new的指针,但确保在“指针”超出作用域的地方释放内存。

因此,在c++社区编码指南中,避免显式的new和delete是一个正式的条款:指南R.11。

新就是新目标。

Recall why goto is so reviled: while it is a powerful, low-level tool for flow control, people often used it in unnecessarily complicated ways that made code difficult to follow. Furthermore, the most useful and easiest to read patterns were encoded in structured programming statements (e.g. for or while); the ultimate effect is that the code where goto is the appropriate way to is rather rare, if you are tempted to write goto, you're probably doing things badly (unless you really know what you're doing).

New也类似——它经常被用来使事情变得不必要的复杂和难以阅读,最有用的使用模式可以被编码到各种各样的类中。此外,如果您需要使用任何新的使用模式,而这些模式还没有标准类,您可以编写自己的类来编码它们!

我甚至认为new比goto更糟糕,因为需要对new和delete语句进行配对。

像goto一样,如果您认为需要使用new,那么您可能做得很糟糕——特别是如果您在一个类的实现之外这样做,这个类的目的是封装您需要做的任何动态分配。

以上所有正确答案还有一点,这取决于你在做什么类型的编程。在Windows中开发内核,例如->堆栈受到严重限制,您可能无法像在用户模式中那样处理页面错误。

在这样的环境中,新的或类似c的API调用是首选的,甚至是必需的。

当然,这只是规则的一个例外。