如何在C ++中选择堆分配与堆栈分配?

时间:2011-11-01 21:27:37

标签: c++ memory-management scope c++11 software-design

将其与其他语言区分开来的C ++功能之一是能够将复杂对象分配为成员变量或局部变量,而不必始终使用new分配它们。但这导致了在任何特定情况下可以选择的问题。

是否有一些很好的标准可供选择如何分配变量?我什么时候应该将成员变量声明为直接变量而不是作为引用或指针?我何时应该使用new分配变量而不是使用在堆栈上分配的局部变量?

2 个答案:

答案 0 :(得分:22)

  

使其与其他语言区别开来的C ++功能之一

...是手动进行内存分配。但是让我们把它放在一边:

  • 当一个对象必须长寿时分配在堆上,即必须比某个范围更长,并且昂贵或不可能复制或移动,
  • 在一个对象很大的时候在堆上进行分配(如果你想要安全的话,那么大可能意味着几千字节)以防止堆栈溢出,即使该对象只是暂时需要,
  • 如果您使用的是pimpl (compiler firewall) idiom,,则
  • 在堆上进行分配
  • 在堆上分配可变大小的数组,
  • 在堆栈上分配,否则因为它更方便。

请注意,在第二条规则中,“大对象”是指类似

的内容
char buffer[1024 * 1024];  // 1MB buffer

但不是

std::vector<char> buffer(1024 * 1024);

因为第二个实际上是一个非常小的对象,它包含一个指向堆分配缓冲区的指针。

对于指针与值成员:

  • 如果需要堆分配,请使用指针
  • 如果您正在共享结构,请使用指针
  • 使用多态性的指针或引用,
  • 如果从客户端代码中获取对象并且客户端承诺保持活动,则使用引用,
  • 在大多数其他情况下使用值。

当然建议在适当的时候使用智能指针。请注意,您可以在堆分配的情况下使用引用,因为您始终可以delete &ref,但我不建议这样做。引用是伪装的指针,只有一个差异(引用不能为空),但它们也表示不同的意图。

答案 1 :(得分:2)

larsmans的回答几乎没有。

在堆栈上分配通常可以简化资源管理,您不必担心内存泄漏或所有权等问题。GUI library围绕此观察建立,请检查“Everything属于某个地方”和“谁拥有小部件” 。“

如果您在堆栈上分配所有成员,则默认副本ctor和默认op =通常就足够了。如果在堆上分配成员,则必须小心如何实现它们。

如果在堆栈上分配成员变量,则必须显示成员的定义。如果在堆上分配它,那么您可以转发声明该成员。我个人喜欢前瞻性声明,它减少了依赖性。