内存管理 * ============= 心得: C语言的内存管理,主要 内存主要分为5个区,**栈区**、**堆区**、**全局/静态存储区**、**常量存储区**、**代码区** 文本段,也称为代码区或简称为文本,是目标文件或内存中的程序段之一,其中包含可执行指令。 作为内存区域,可以将文本段放置在堆或堆栈下方,以防止堆和堆栈溢出覆盖它。 一般情况下,文本段是可共享的,因此对于频繁执行的程序(例如文本编辑器、C 编译器、shell 等),只需要在内存中保存一个副本。 代码段一般是只读的,以防止程序意外修改其指令。 初始化数据区(Initialized Data Segment) 初始化数据区,也简称为数据段。数据段是静态内存分配,其中包含由程序中初始化的全局变量和静态变量,常量。 数据段不是只读的,因为变量的值可以在运行时更改。 .. code-block:: c char s[] = "hello world"; //全局变量 int a = 1; //全局变量 const char* string = "hello world"; static int b = 1; ////内部变量或外部变量 未初始化数据区(Uninitialized Data Segment) 未初始化的数据区也叫做bss区(bss segment),该段中的数据在程序开始执行之前由内核初始化为0,未初始化的数据从数据段的末尾开始,包含所有初始化为零或源代码中没有显式初始化的全局变量和静态变量。 static int i; //内部变量或外部变量 int j; //全局变量 栈区(Stack) 栈区是由编译器自动分配释放的。 当一个函数被调用,该函数返回地址和一些关于调用的信息,比如某些寄存器的内容,被存储到栈区; 然后这个被调用的函数再为它的自动变量和临时变量在栈区上分配空间,这就是C实现函数递归调用的方法。每执行一次递归函数调用,一个新的栈框架就会被使用,这样这个新实例栈里的变量就不会和该函数的另一个实例栈里面的变量混淆; 在函数被调用时,其参数也会被压入发起调用的进程栈中,并且等到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进后厨特点,所以栈特别方便用来保存/恢复调用现场。 堆区(Heap) 堆区从bss段的尾部开始,在使用malloc和calloc函数发生动态内存分配申请时,会从堆区的低地址开始分配。堆区域由进程中的所有共享库和动态加载的模块共享。 .. code-block:: c char *p=(char*)malloc(sizeof(char)); /* memory allocating in heap segment */ 例子 用shell命令查看可执行文件的内存分布。 1.先看一段简单程序的内存分布 .. code-block:: c #include int main(void) { return 0; } .. code-block:: console [narendra@CentOS]$ gcc memory-layout.c -o memory-layout [narendra@CentOS]$ size memory-layout text data bss dec hex filename 960 248 8 1216 4c0 memory-layout 2.增加一个未初始化的全局变量时,存放在了bss段 .. code-block:: c #include int global; /* Uninitialized variable stored in bss*/ int main(void) { return 0; } .. code-block:: console [narendra@CentOS]$ gcc memory-layout.c -o memory-layout [narendra@CentOS]$ size memory-layout text data bss dec hex filename 960 248 12 1220 4c4 memory-layout 3.增加一个未初始化的静态变量时,存放在了bss段 .. code-block:: c #include int global; /* Uninitialized variable stored in bss*/ int main(void) { static int i; /* Uninitialized static variable stored in bss */ return 0; } .. code-block:: console [narendra@CentOS]$ gcc memory-layout.c -o memory-layout [narendra@CentOS]$ size memory-layout text data bss dec hex filename 960 248 16 1224 4c8 memory-layout 4. 给静态变量初始化后,存放在了data段 .. code-block:: c #include int global; /* Uninitialized variable stored in bss*/ int main(void) { static int i = 100; /* Initialized static variable stored in DS*/ return 0; } .. code-block:: console [narendra@CentOS]$ gcc memory-layout.c -o memory-layout [narendra@CentOS]$ size memory-layout text data bss dec hex filename 960 252 12 1224 4c8 memory-layout 5.给全局变量初始化后,也存放在了data段 .. code-block:: c #include int global = 10; /* initialized global variable stored in DS*/ int main(void) { static int i = 100; /* Initialized static variable stored in DS*/ return 0; } .. code-block:: console [narendra@CentOS]$ gcc memory-layout.c -o memory-layout [narendra@CentOS]$ size memory-layout text data bss dec hex filename 960 256 8 1224 4c8 memory-layout