在C++中使用新的和不使用它有什么不同?

在C++中使用新的和不使用它有什么不同?,c++,allocation,C++,Allocation,两者的区别是什么 Kwadrat* k1 = new Kwadrat(1,2,3); k1->field = 0; Kwadrat k2(1,2,3); k2.field = 0; 第一个是指向已分配内存的指针,第二个是对象,它在系统堆栈上的位置?为什么第二个更糟?当我们使用第一个时,第二个时?堆上的动态分配使用新的: Kwadrat*k1=新Kwadrat1,2,3; 在堆栈上创建对象而不创建新对象: Kwadrat k21,2,3 查看有关堆栈和堆的详细讨论。很好地比较了两者,同时也

两者的区别是什么

Kwadrat* k1 = new Kwadrat(1,2,3);
k1->field = 0;
Kwadrat k2(1,2,3);
k2.field = 0;

第一个是指向已分配内存的指针,第二个是对象,它在系统堆栈上的位置?为什么第二个更糟?当我们使用第一个时,第二个时?

堆上的动态分配使用新的: Kwadrat*k1=新Kwadrat1,2,3; 在堆栈上创建对象而不创建新对象: Kwadrat k21,2,3

查看有关堆栈和堆的详细讨论。很好地比较了两者,同时也为您提供了更多的细节

对于一个危险的小总结:

必须删除用new创建的对象,否则代码将出现内存泄漏 您不必担心手动删除堆栈上创建的对象,因为C++会为您处理这些问题。 如果尝试非常大的分配,堆栈可能溢出。 至于你应该使用哪一个,这取决于你要创建的对象的预期范围
堆上的动态分配使用新的: Kwadrat*k1=新Kwadrat1,2,3; 在堆栈上创建对象而不创建新对象: Kwadrat k21,2,3

查看有关堆栈和堆的详细讨论。很好地比较了两者,同时也为您提供了更多的细节

对于一个危险的小总结:

必须删除用new创建的对象,否则代码将出现内存泄漏 您不必担心手动删除堆栈上创建的对象,因为C++会为您处理这些问题。 如果尝试非常大的分配,堆栈可能溢出。 至于你应该使用哪一个,这取决于你要创建的对象的预期范围
new在堆上分配一个对象。第二个示例在堆栈上分配内存。一旦分配k2的函数返回内存将不再有效,当然会首先调用k2的析构函数。如果希望对象比创建它的函数寿命长,则需要使用new。

new在堆上分配对象。第二个示例在堆栈上分配内存。一旦分配k2的函数返回内存将不再有效,当然会首先调用k2的析构函数。如果希望对象比创建它的函数寿命长,则需要使用new。

使用new动态地在堆上创建对象,这意味着即使指针k1*超出范围,它也会持续存在

这可能很方便,但如果它超出范围,并且您没有在其周围保留指针的副本,则会永久丢失并导致内存泄漏。这意味着,只要程序执行,您就会失去该资源使用的空间。这是使用new动态分配内存的缺点,您必须跟踪它并使用delete操作符手动释放它,这需要额外的工作

用另一种方法创建一个堆栈对象,一旦它离开作用域就会被销毁,这通常是可取的

通常,在对new使用动态内存创建时,人们通过将动态创建的对象包装到另一个对象中来获得类似堆栈的功能,当对象超出范围时,该对象将被破坏。这种模式称为资源获取模式。这对于引用计数非常有用,因此您的对象仍然可以在范围外持久化,但当不再有任何对象引用它们时将被销毁。

使用new在堆上动态创建一个对象,这意味着即使指针k1*超出范围,它也会持久化

这可能很方便,但如果它超出范围,并且您没有在其周围保留指针的副本,则会永久丢失并导致内存泄漏。这意味着,只要程序执行,您就会失去该资源使用的空间。这是使用new动态分配内存的缺点,您必须跟踪它并使用delete操作符手动释放它,这需要额外的工作

用另一种方法创建一个堆栈对象,一旦它离开作用域就会被销毁,这通常是可取的

通常,在对new使用动态内存创建时,人们通过将动态创建的对象包装到另一个对象中来获得类似堆栈的功能,当对象超出范围时,该对象将被破坏。这种模式称为资源获取模式。这对于引用计数非常有用,因此您的对象仍然可以在范围外持久化,但当不再有任何对象引用它们时将被销毁。

new允许您为请求的分配指定存储。通过new/new[]的分配通常在堆上,例如包装malloc,但最终由实现定义。此外,编译器可能有足够的信息在某些情况下绕过这一点

它在哪里,在系统堆栈上

技术上,通常会将C++写入抽象机器的规范。

但通常情况下,是的-对象是在 线程的堆栈

为什么第二个更糟?我们什么时候用第一个,什么时候用第二个

第二个应该是您的默认值,因为它非常清楚,编译器为您管理其生存期和分配,而且速度非常快。这方面的一些例外情况包括:

当您有较大的分配时,堆栈大小相对较小 有时,当您希望与其他线程共享分配时 当您想要将分配传递给另一个线程时 当您希望对象超出方法的范围时,通常会使用智能指针或其他容器来正确删除对象。 简言之,使用第二种方法可能出现的错误要少得多,通过通用系统分配器创建分配所花费的时间也要少得多。

new允许您为请求的分配指定存储空间。通过new/new[]的分配通常在堆上,例如包装malloc,但最终由实现定义。此外,编译器可能有足够的信息在某些情况下绕过这一点

它在哪里,在系统堆栈上

技术上,通常会将C++写入抽象机器的规范。

但通常情况下,是的——对象是在线程堆栈上分配的

为什么第二个更糟?我们什么时候用第一个,什么时候用第二个

第二个应该是您的默认值,因为它非常清楚,编译器为您管理其生存期和分配,而且速度非常快。这方面的一些例外情况包括:

当您有较大的分配时,堆栈大小相对较小 有时,当您希望与其他线程共享分配时 当您想要将分配传递给另一个线程时 当您希望对象超出方法的范围时,通常会使用智能指针或其他容器来正确删除对象。
简言之,使用第二种方法出错的可能性要小得多,通过通用系统分配器创建分配所花费的时间也要少得多。

为什么第二种方法更糟糕?-谁说的?忽略它们。答案是heap new vs stack。好与坏都没有意义。当您希望对象在离开范围时离开时使用堆栈;当对象需要在其创建时所在的函数之外持久化时,请使用“新建”。通常您希望实际使用第二个版本,除非您确实需要对象的活动范围以超出其范围。为什么第二个版本更糟糕谁说的?忽略它们。答案是heap new vs stack。好与坏都没有意义。当您希望对象在离开范围时离开时使用堆栈;当对象需要在其创建时所在的函数之外持久化时,请使用new。通常您希望实际使用第二个版本,除非您确实需要对象的livespan以超出其范围。new在现实世界中是否实际包装malloc?我真的不知道,但我认为没有理由它应该使用malloc,而不是使用任何平台特定的函数来实现malloc。是的-new/new[]可以调用malloc。C++实现可以通过平台/体系结构发生很大的变化。@ Deln-贾斯廷正确地指出,如果不喜欢默认的分配机制,可以更改新的。当然C++操作符new不仅仅是内存分配,它也调用对象的构造函数。我不是想问这个答案,它只是提醒我,实际上不知道新分配内存的实现方式有多普遍。另外,我很愚蠢,我认为使用malloc是这一级别上这类分配器的参考通用实现。当然,可以进行改进和专门化-因此,该语言为您提供了广泛定制它的能力的原因。在现实世界中,new是否真的包装了malloc?我真的不知道,但我认为没有理由它应该使用malloc,而不是使用任何平台特定的函数来实现malloc。是的-new/new[]可以调用malloc。C++实现可以通过平台/体系结构发生很大的变化。@ Deln-贾斯廷正确地指出,如果不喜欢默认的分配机制,可以更改新的。当然C++操作符new不仅仅是内存分配,它也调用对象的构造函数。我不是想问这个答案,它只是提醒我,实际上不知道新分配内存的实现方式有多普遍。另外,我很愚蠢,我认为使用malloc是这一级别上这类分配器的参考通用实现。当然,可以进行改进和专门化——因此,该语言提供了广泛定制的能力。