系统相关
首页 > 系统相关> > C/C++内存模型

C/C++内存模型

作者:互联网

1、存储区域

1)Heap堆

由malloc分配的内存块,由程序员控制内存块的申请和释放(malloc/free)。如果申请的堆内存没有被释放掉,在程序结束时操作系统会自动回收。涉及问题:缓冲区溢出、内存泄漏。

2)Free store 自由存储区

由new分配的内存块。由程序员控制内存块的申请和释放(new/delete)。如果申请的堆内存没有被释放掉,在程序结束时操作系统会自动回收。涉及问题:缓冲区溢出、内存泄漏。

3)stack 栈

由编译器负责分配和清除内存存储区。存放具备变量、函数参数。存放在栈中的数据旨在当前函数及下一层函数中有效,一旦函数返回,这些数据占用的内存空间自动释放。

4).bss段和.data段 全局/静态存储区

全局变量和静态变量被分配到同一块内存中。在C语言中,未初始化的放在.bss段中,初始化的放在.data段中;在C++里不区分。

5).rodata段 常量存储区

存放常量,不允许修改(通过非正常手段可以达到修改目的)

6).text段 代码区

存放代码(如函数),不允许修改(类似常量存储区),但可以执行(不同常量存储区)

2、C/C++内存模型

C分为四个区:堆、栈、静态全局变量区、常量区。

C++分为五个区:堆、栈、静态全局变量区、常量区、自由存储区。

根据c/c++对象生命周期不同,c/c++的内存模型有三种不同的内存区域,即自由存储区,动态区、静态区。

而代码虽然占内存,但不属于c/c++内存模型的一部分。

3、linux 中程序内存分布

BSS是“Block Started by Symbol”的缩写,意为“以符号开始的块”,是Unix连接器产生的未初始化数据段,其它的段分别是包含代码的.text段和包含已初始化数据的.data段。BSS段的变量只有名称和大小但没有值。此名称被许多文件格式使用,包括PE。“以符号开始的块”指的是编译器处理未初始化数据的地方。BSS段不包含任何数据,只是简单的维护开始和结束地址,以便内存区能在运行时被有效的清零。BSS段在应用程序中的二进制镜像文件中并不存在。

在采用段式内存管理的架构中(如:intel的8086系统),BSS段通常用来存放程序中未初始化全局变量的一块内存区域,一般在初始化时,BSS段部分将会清零。BSS段属于静态内存分配,即程序一开始就将其清零了。

在C语言中之类的程序编译完成之后,已经初始化的全局变量保存在.data段中,未初始化的全局变量保存在.bss段中。

.text和.data段都在可执行文件中(在嵌入式系统里一般是固化在镜像文件中),由系统从可执行文件中加载。而.bss段不在可执行文件中加载,由系统初始化。

下图未可执行代码存储时结构和运行时结构对照:

之所以分成这么多个区域,主要基于以下考虑:

用例:

int a = 0;    //a在全局已初始化数据区 
char *p1;    //p1在BSS区(未初始化全局变量) 
main() 
{
  int b;    //b在栈区
  char s[] = "abc"; //s为数组变量,存储在栈区,
  //"abc"为字符串常量,存储在已初始化数据区
  char *p1,p2;  //p1、p2在栈区
  char *p3 = "123456"; //123456\0在已初始化数据区,p3在栈区 
  static int c =0;  //C为全局(静态)数据,存在于已初始化数据区
  //另外,静态数据会自动初始化
  p1 = (char *)malloc(10);//分配得来的10个字节的区域在堆区
  p2 = (char *)malloc(20);//分配得来的20个字节的区域在堆区
  free(p1);
  free(p2);
}

 

标签:栈区,初始化,存储,模型,C++,BSS,内存,全局变量
来源: https://www.cnblogs.com/zhongqifeng/p/14652775.html