C++内存空间

C++ memory spaces

本文关键字:空间 内存 C++      更新时间:2023-10-16

我已经通读了C++标准。然而,分配了什么类型的内存空间,以及它与作用域和生存期之间的关系还不太清楚。我会给出我的基本理解,但如果大师们能够通过附带规则/例子来纠正/加强这一点,那将有所帮助。

我们将简化单个线程应用程序:

  1. 堆动态内存通常使用new/malloc
  2. 堆栈-例如自动变量的位置
  3. 静态空间——静态变量去哪里
  4. 程序是否可以访问实现使用的其他类型的空间
  5. 虽然C++标准指的是抽象机器,但还有什么其他可用的内存空间

范围:与标识符(即名称/参考)的可见性有关

寿命:分配/取消分配内存的开始/结束时间

其他相关问题是重写malloc等的任何算法/白皮书。

  • "堆"/动态分配new/delete malloc/realloc/free

    • 直到delete/realloc(p, 0)/free的寿命
  • 堆栈-用于许多函数参数和函数局部变量

    • 最小封闭作用域退出之前的生存期/无论是for/while/if还是{}-封闭块或函数
    • (有时参数/var可能在CPU寄存器中,但离开作用域的任何副作用有时都会发生,"就好像"它们在堆栈上一样)
  • 全局、命名空间作用域变量、类/结构静态成员、函数静态变量/大多数编译器/OS支持在内存中对只读(即const)和读写变量进行分组/分离(因此它们可以使用CPU内存管理强制执行只读内存访问),并且通常从静态初始化到非0的数据初始化到0(因此它们可以简单地映射到包含初始非0值的可执行图像的区域)

    • 无论它们在内存中是如何分组的,需要运行时初始化的函数本地静态在函数第一次被调用时执行初始化,而对于非函数变量,范围是由每个翻译单元/对象文件内的有序结构、对象文件之间的未指定顺序来定义的,所有这些都发生在进入main()之前,和CCD_ 15退出后的销毁顺序相反
    • 一个例外是运行时加载的对象(例如dlopen()等),可以预见,这些对象在加载时执行任何必要的初始化,并且对象在卸载或程序终止之前一直处于作用域中
  • 线程本地存储:通常通过在函数的"堆栈"开始时保留内存来实现,在堆栈中,生存期可以与线程的相匹配

  • 正如Kerrek SB所评论的,可以为抛出的对象留出空间,将它们的生存期与展开堆栈脱钩,但细节取决于实现;该区域将在"按值"抛出时使用,寿命将延长到第一个不重抛出同一对象的catch块的末尾