在C语言中,内存的主要分为下列几部分:
1. Text/Code Segment 文本/代码区
2. Initialized Data Segments 初始化的数据区
3. Uninitialized Data Segments 未初始化的数据区
4. Stack Segment 栈区
5. Heap Segment 堆区
Text/Code Segment 文本/代码区
这个区主要用来保存机器代码,一个可执行对象文件的文本区通常是只读区,可以防止程序被意外修改。文本/代码区可能会被放在堆和栈的下方来防止堆和栈的覆写溢出。
Initialized Data Segments 初始化的数据区
初始化的数据区存储了所有的初始化了的全局的,静态的,常量的,外部的变量。这些变量没有在函数内部定义或者是以静态的方式在函数内部定义了,比如下面两种情况:
int val = 3; char string[] = "Hello World";
这些变量最初是保存在只读内存中(Text/Code Segment 文本/代码区中),然后被拷贝到了初始化的数据区。
Uninitialized Data Segments 未初始化的数据区
未初始化的数据区,又称作BSS (Block Started by Symbol),这个区一般紧连着初始化的数据区,用来保存所有的初始化为0的全局变量和静态变量,或者没有初始化,比如 static int i;将会存在BSS中。
Stack Segment 栈区
栈区是紧连着堆区的,堆和栈的增长方向相反,当堆和栈的指针重合时,此时内存被耗尽。栈区是以后进先出的机制运行的,通常在内存的高地址处。当一个函数被调用时,该函数的返回地址和调用者的环境信息被保存在栈中,新调用的函数再在栈上开辟空间保存自动和临时变量,这就是递归函数的运行机制。当一个递归函数调用它本身时,一个新的栈格被使用,所以这些变量不会跟上次递归的变量相互干扰。栈区主要保存一些局部变量。
Heap Segment 堆区
堆区主要用来动态分配内存。通过malloc, realloc和free来管理。堆区被所有线程,公用库,动态加载模块所共享。
关于堆和栈的区别,可参见我的另一篇博客Stack and Heap 堆和栈的区别。