C++堆栈与堆分配

Kil*_*efi 9 c++ memory-management

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

我无法想到任何情况,使用堆栈分配是必要的或更好的.也许在嵌入式系统中进行某种优化?

Ton*_*roy 16

使用自动(堆)分配每当功能范围-或控制块的范围,如for,while,if在函数内部等-是用于寿命对象需要的良好匹配.这样,如果对象拥有/控制任何资源,例如动态分配的内存,文件句柄等等 - 它们将在析构函数调用期间被释放,因为该范围被保留.(当垃圾收集器结束时,不会出现一些不可预知的情况).

只有new在有明确需要时才使用,例如:

  • 需要对象比函数范围更长寿,

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

  • 有一个指向基类的指针容器,然后可以多态处理(即使用虚拟调度到派生类函数实现),或者

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

    • 如果这是唯一的原因,你正在使用动态分配,以及你想绑在你的功能范围对象的生命周期,你应该使用本地std::unique_ptr<>管理的动态内存,并确保它被释放不管你怎么离开范围:通过return,throw,break等.(您也可以使用std::unique_ptr<>数据成员在class/ struct管理对象拥有的内存.)

Mathieu Van Nevel在下面评论了C++ 11移动语义 - 相关性是,如果堆栈上有一个控制大量动态分配(堆)内存的小型管理对象,则移动语义可以提供额外保证和细粒度控制当管理对象将其资源移交给其他代码所拥有的另一个管理对象时(通常是调用者,但可能是其他一些容器/对象注册).这种切换可以避免即使在瞬间复制/复制堆上的数据.此外,省略返回值优化通常允许名义上自动/堆栈托管的变量直接构建在一些内存中,它们最终被分配/返回,而不是稍后复制.