2

和有什么区别

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

第一个是指向分配内存的指针,第二个是对象(它在哪里,在系统堆栈上?)为什么第二个更糟?我们什么时候用第一个,什么时候用第二个?

4

4 回答 4

2

堆上的动态分配(使用new):
Kwadrat* k1 = new Kwadrat(1,2,3);
在堆栈上创建对象(不使用new):
Kwadrat k2(1,2,3);

查看这个 Stack Overflow 问题,了解有关堆栈和堆的扩展讨论。Brian R. Bondy 的回答很好地比较了两者,而Jeff Hill 的回答为您提供了更多细节。

对于一个危险的小总结:

  • 您必须delete使用您创建的对象new,否则您的代码将遭受内存泄漏
  • 您不必担心手动删除在堆栈上创建的对象,因为 C++资源分配是初始化 (RAII)会为您处理这些
  • 如果您尝试非常大的分配,堆栈可能会溢出。
  • 至于你应该使用哪一个,这取决于你正在创建的对象的预期范围
于 2012-08-10T15:56:36.723 回答
2

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

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

以另一种方式执行此操作会创建一个堆栈对象,该对象一旦离开范围就会被销毁,这通常是可取的。

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

于 2012-08-10T15:57:39.410 回答
0

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

于 2012-08-10T15:57:03.360 回答
0

new允许您为请求的分配指定存储。分配 vianew/new[]通常在堆上(例如 wrapping malloc),但最终由实现定义。同样,在某些情况下,编译器可能有足够的信息来绕过它。

它在哪里,在系统堆栈上?

从技术上讲,您通常会将 C++ 编写到抽象机器的规范中。

但通常,是的 - 对象是在线程的堆栈上分配的。

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

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

  • 当您有大量分配时(堆栈大小相对较小)
  • 有时当您想与另一个线程共享分配时
  • 当您想将分配传递给另一个线程时
  • 当您希望对象超出方法的范围时,您通常会使用智能指针或其他容器来正确删除对象。

简而言之,可能出错的情况要少得多(使用第二个),并且通过通用系统分配器创建分配所花费的时间要少得多。

于 2012-08-10T15:57:48.363 回答