Skip to content

Latest commit

 

History

History
95 lines (48 loc) · 7.97 KB

存储区.md

File metadata and controls

95 lines (48 loc) · 7.97 KB

必看图解

img

静态存储区

在C++中,静态存储区(Static Storage Area)是指在程序生命周期内始终存在的存储区域,其内存分配和释放是由编译器自动完成的。常见的放在静态存储区的变量包括:

  1. 静态全局变量(Static Global Variables):在函数外部定义的变量,其作用域仅限于当前文件,可以在整个程序的生命周期内访问。
  2. 静态局部变量(Static Local Variables):在函数内部定义,并用 static 修饰的变量,其作用域仅限于当前函数,但其生命周期是整个程序的生命周期,即使函数返回,该变量仍然存在。
  3. 常量(Constants):在程序中定义的常量,如 const int MAX_SIZE = 100;,其值在程序运行期间不会改变,因此通常放在静态存储区中。
  4. 字符串常量(String Literals):在程序中用双引号括起来的字符串常量,如 "Hello, world!",它们也被存储在静态存储区中,并且在整个程序的生命周期内都存在。

需要注意的是,静态存储区中的变量和常量是在程序启动时就已经分配好内存的,并且它们的内存空间是在程序结束时才被释放的,因此应该避免在静态存储区中存储过多的数据,以免占用过多的内存空间。

静态存储区通常可以分为以下几个部分:

  1. 数据段(.text)(Data Segment)(代码段):用于存储已初始化的全局变量和静态局部变量。在编译时,这些变量的初始值会被写入可执行文件的代码段中,程序运行时会将代码段的内容加载到静态存储区。
  2. 读写段(BSS段)(Block Started by Symbol):用于存储未初始化的全局变量和静态局部变量。BSS段在可执行文件中只保存变量的名称和大小,并在程序运行时分配内存并初始化为零值。
  3. 常量区(只读数据段)(.rodata):用于存储常量数据和虚表

静态的都是编译器做得事情,编译器做得事情,就是放到静态存储区

动态存储区(堆)

在C++中,动态存储区(Dynamic Storage Area)是指在程序运行期间可以动态地分配和释放内存的存储区域,通常使用new和delete运算符进行内存的分配和释放。常见的放在动态存储区的变量和数据结构包括:

  1. 动态分配的变量(Dynamic Variables):通过new运算符动态分配的变量,其生命周期可以在程序运行期间动态地控制。
  2. 动态分配的数组(Dynamic Arrays):通过new运算符动态分配的数组,可以根据需要动态地调整数组的大小。
  3. 动态分配的结构体和类(Dynamic Structs and Classes):通过new运算符动态分配的结构体和类,可以创建动态的对象,并在程序运行期间动态地控制它们的生命周期。

堆和栈

栈是程序自动分配,堆是程序员自己分配

栈(Stack)是一种自动分配和释放内存空间的数据结构,其内存空间由编译器自动分配和释放,存储的数据以"后进先出"(Last-In-First-Out,LIFO)的方式进行访问,通常用于存储函数调用的上下文信息、局部变量和临时数据等。栈的大小在程序编译时就已经确定,因此它对于程序的性能和内存管理都有很好的优化效果。

堆(Heap)是一种手动分配和释放内存空间的数据结构,其内存空间由程序员手动申请和释放,存储的数据可以以任意顺序进行访问,并且在程序运行期间可以动态地分配和释放内存空间。堆的大小在程序运行时动态变化,因此需要程序员手动管理内存,以避免内存泄漏和其他内存相关的问题。

当你编写一个程序并执行时,操作系统会为该程序分配一块内存空间,其中包括栈(stack)用于存储函数调用和局部变量。栈是一种后进先出(LIFO)结构,用于管理函数的调用和返回。在函数调用时,会为该函数分配一块栈帧(stack frame),栈帧包含函数的局部变量、函数参数、返回地址等信息

编译器会根据函数的定义和变量的作用域,在栈帧中为局部变量分配内存空间。编译器会在编译阶段确定局部变量相对于栈帧的偏移量,并生成相应的访问指令。当程序执行到函数内部时,通过偏移量和栈指针(stack pointer)可以计算出局部变量在栈帧中的具体位置。然后,程序可以使用相应的指令来读取和写入局部变量的值。

操作系统本身并不直接关注和访问函数的局部变量,它主要提供了一种机制来管理进程的内存空间,并确保程序可以按照预期的方式访问和操作内存。这些操作是由编译器和运行时环境来处理的,而不是操作系统本身的职责。

程序代码区

程序代码区(Code Segment)也被称为只读数据区(Read-Only Data Segment)或文本段(Text Segment),是指存储程序执行代码的区域。它通常位于程序的虚拟地址空间中的一个固定位置,并且其内存空间的大小在程序编译时就已经确定

在大多数操作系统中,程序代码区通常位于可执行文件的只读数据段中,当程序被加载到内存中时,代码区会被映射到进程的虚拟地址空间中,以供程序执行。由于程序代码区存储的是只读的指令代码,因此它通常是只读的,不允许程序对其进行写操作。

需要注意的是,程序代码区与程序的静态存储区是不同的概念。静态存储区存储的是程序中定义的静态变量、全局变量、常量和字符串常量等数据,而程序代码区存储的是程序执行的指令代码。在内存中,程序代码区和静态存储区通常是分开的,它们的内存空间是不同的,也有不同的访问权限和特性。

程序数据段

程序数据段(Data Segment),也称为全局数据段或静态数据段,是程序在运行时使用的一部分内存,用于存储静态分配的全局变量和静态局部变量(即使用static关键字定义的局部变量)以及常量数据。

在大多数操作系统中,程序数据段通常被划分为两个不同的部分:已初始化数据段(Initialized Data Segment)和未初始化数据段(Uninitialized Data Segment),也称为BSS段(Block Started by Symbol)。

  1. 已初始化数据段: 已初始化数据段用于存储静态分配的全局变量和静态局部变量,以及一些常量数据,这些变量在程序运行之前已经被初始化。已初始化数据段通常被存储在可执行文件的数据段中,并在程序加载时被映射到内存中。已初始化数据段可以通过const关键字来定义只读常量。例如:

    int global_var = 10;             // 全局变量,已初始化
    static int static_var = 20;      // 静态局部变量,已初始化
    const char* const_str = "hello"; // 只读常量字符串
  2. 未初始化数据段: 未初始化数据段用于存储静态分配的全局变量和静态局部变量,这些变量在程序运行之前没有被初始化,因此其值被初始化为0或空。未初始化数据段通常被存储在可执行文件的BSS段中,并在程序加载时被映射到内存中。未初始化数据段的大小在编译时就已经确定,但在运行时被初始化为0或空。例如:

    int global_var2;        // 全局变量,未初始化,值为0
    static int static_var2; // 静态局部变量,未初始化,值为0

需要注意的是,程序数据段是只读的,它们的内容不能被修改。如果需要在程序运行时动态分配内存(例如使用newmalloc),则应该使用堆或栈内存,而不是程序数据段。