C++ 堆栈与堆分配

标签 c++ memory-management

我想知道在 C++ 中什么时候应该在堆栈上分配一个类?我有很强的 Java 背景,在 Java 中,所有类都使用 new 关键字分配在堆上。在 C++ 中,我可以在堆栈和堆分配之间进行选择,但现在引入了智能指针,分配所有不转移所有权的内容更有意义 std::unique_ptr

我真的想不出有什么情况需要或更好地使用堆栈分配。也许是为了对嵌入式系统进行某种优化?

最佳答案

每当函数作用域或控制 block 的作用域(例如 for)时,使用自动(堆栈)分配, while , if等在函数内部 - 非常适合对象所需的生命周期。这样,如果对象拥有/控制任何资源,例如动态分配的内存、文件句柄等——它们将在析构函数调用期间被释放,因为该范围已离开。 (当垃圾收集器结束时,不会在某个不可预测的后期时间)。

只使用new如果有明确的需求,例如:

  • 需要对象的生命周期比函数范围长,

  • 将所有权移交给其他代码

  • 拥有一个指向基类的指针容器,然后您可以对其进行多态处理(即使用虚拟分派(dispatch)派生类函数实现),或者

  • 特别大的分配会占用大量堆栈(您的操作系统/进程将“协商”一个限制,通常在 1-8+ 兆字节范围内)

    • 如果这是您使用动态分配的唯一原因,并且您确实希望将对象的生命周期绑定(bind)到函数中的范围,则应使用本地 std::unique_ptr<>管理动态内存,并确保无论您如何离开范围,它都会被释放:by return , throw , break等等。(您也可以在 std::unique_ptr<>/class 中使用 struct 数据成员来管理对象拥有的任何内存。)

Mathieu Van Nevel 在下面评论了 C++11 的移动语义——相关的是,如果你在堆栈上有一个小的管理对象来控制大量动态分配的(堆)内存,移动语义会提供额外的保证和良好的- 管理对象何时将其资源移交给其他代码(通常是调用者,但可能是其他容器/对象寄存器)拥有的另一个管理对象的粒度控制。这种移交可以避免堆上的数据被复制/复制,即使是暂时的。此外,elisionreturn-value-optimisation 通常允许名义上的自动/堆栈托管变量直接在最终被分配/返回的某些内存中构造,而不是稍后复制到那里。

关于C++ 堆栈与堆分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36646493/

相关文章:

c++ - RtAudio-播放wav文件中的样本

C++ , winapi 比较两个 WCHAR * 字符串

PHP数组操作时内存使用突然增加

memory-management - memory_get_peak_usage 与实际 php 进程内存使用量的区别

java - volatile 贵吗?

C++ 从此处实例化时出现 std::set 错误

c++ - C++中的状态机通过单例?

c++ - 缺少 Visual Studio 2010 Express 64 位属性

ios - 这些不同的 dealloc 策略的优缺点是什么?

c++ - 是否可以从现有基类动态分配派生类所需的额外内存?