C++堆栈与堆分配
C++ stack vs heap allocation
我想知道什么时候应该在C++中的堆栈上分配一个类?我有很强的Java背景,在Java中,所有类都是使用new
关键字在堆上分配的。在C++中,我可以在堆栈和堆分配之间进行选择,但现在引入了智能指针,用std::unique_ptr
分配所有不转移所有权的东西更有意义。
我真的想不出在任何情况下,使用堆栈分配是必要的或更好的。也许是为了在嵌入式系统中进行某种优化?
只要函数范围-或函数内的控制块(如for
、while
、if
等)的范围-与对象所需的生存期很匹配,就使用自动(堆栈)分配。这样,如果对象拥有/控制任何资源,例如动态分配的内存、文件句柄等,那么在析构函数调用过程中,这些资源将在保留该范围时被释放。(在以后某个不可预测的时间,当垃圾收集器结束时,不会发生这种情况)。
只有在明确需要时才使用new
,例如:
-
需要对象的寿命超过功能范围,
-
将所有权移交给其他代码
-
有一个指向基类的指针容器,然后可以对其进行多态处理(即使用虚拟调度来实现派生类函数),或者
-
一个特别大的分配会占用堆栈的大部分(您的操作系统/进程将"协商"一个限制,通常在1-8兆字节以上的范围内)
- 如果这是您使用动态分配的唯一原因,并且您确实希望对象的生存期与函数中的作用域绑定,则应使用本地
std::unique_ptr<>
来管理动态内存,并确保无论您如何离开作用域都会释放它:通过return
、throw
,break
等。(您也可以在class
/struct
中使用std::unique_ptr<>
数据成员来管理对象拥有的任何内存。)
- 如果这是您使用动态分配的唯一原因,并且您确实希望对象的生存期与函数中的作用域绑定,则应使用本地
Mathieu Van Nevel在下面评论了C++11移动语义——相关性在于,如果堆栈上有一个小的管理对象,它控制着大量的动态分配(堆)内存,move语义为管理对象何时将其资源移交给其他代码拥有的另一个管理对象(通常是调用者,但可能是对象的其他容器/寄存器)提供了额外的保证和细粒度控制。这种切换可以避免堆上的数据被复制/复制,即使是暂时的。此外,省略和返回值优化通常允许在一些内存中直接构建名义上自动/堆栈托管的变量,而不是稍后复制到那里。
在大型代码库中,我们对简单的结构对象使用堆栈分配,而对更复杂的类(涉及多态性、内存所有权等),我们总是使用动态分配。
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 从堆栈分配的原始指针构造智能指针
- 在函数范围内在堆栈上分配的数组在离开函数时是否总是被释放?
- 巨大的内存分配:堆栈与堆
- 有效地分配堆栈对象(由函数的值返回)到堆?
- 为什么不能在 Visual C++ 中动态分配堆栈内存?但海湾合作委员会可以做到
- 为什么分配堆内存比分配堆栈记忆更快
- 安全分配堆栈分配的阵列
- 附加到具有非动态分配堆栈的向量
- 是否随作用域分配和解除分配堆栈帧
- 在执行中脱离堆栈对象的范围之前,请分配堆栈对象
- 全局阵列分配 -- 堆栈或堆
- 如何使新操作员超载以分配堆栈
- 具有类作用域的动态分配堆栈内存
- 如何在 Linux 下为可执行文件分配堆栈
- 内存分配堆栈
- 成员函数内存分配堆栈或堆
- 在 c++ 中重新分配堆栈上的对象
- 防止为类和派生类分配堆栈
- 如何防止msvc++为switch语句过度分配堆栈空间?