1、回顾Linux下c内存映像
我们有详细的介绍过C程序在Linux下的内存映像,因为本章的课程需求,我们这里需要回顾一下。
1.1 代码段(只读段)
代码段在编译时就定好了,在程序的运行过程中,不能在代码段去开辟空间,以及释放空间。
1.1.1 ELF头、段头部表、init节
这三个在之前已经介绍过了,在这里我们不再介绍。
以后我们再介绍内存结构时,会直接将这三个节省略。
1.1.2 .text
指令节,也叫代码节,所有函数中的指令都放在了.text节中。
能够与指令直接弄在一起的常量,也随指令一起放在了.text中。
1.1.3 .rodata
常量节,无法直接和指令放在一起的常量,就放在.rodata中。
比如:char *p = "helloworld";
1.2 数据段(可读/可写段)
1.2.1 静态数据段
(1).bss
未初始化的静态变量的空间,都开辟于.bss中。
(2).data
初始化了的静态变量的空间,都开辟于.data。
静态数据段的静态二字是什么意思?
在.bss、.data中为哪些变量开辟空间,是由编译器在编译时决定的,在程序运行的过程中不能随意开辟,也不能随意释放已有变量的空间,像这种在编译阶段完成了变量空间安排的情况,就是静态的。
比如:
int a = 100; //在.data中 int main(void) { ... }
在程序的运行过程中,不能随意.data中开辟一个全局变量空间,也不能释放已经开辟的空间,比如释放变量a的空间。
1.2.2 动态数据段
为什么称为动态的?
变量空间的开辟和释放不是在编译阶段决定的,而是在程序的运行过程中完成的,这就是动态的含义。
(1)堆(手动区)
程序在运行的过程中,通过调用malloc函数来开辟空间,以及调用free来释放空间。
自所以叫手动的,是因为我们在编写程序时,必须亲自动写调用malloc和free函数的代码。
(2)栈(自动区)
函数运行时自动从栈中开辟空间,函数运行结束时又会自动释放开辟的空间,开辟和释放的过程,完全是自动完成的。
从栈里面开辟空间就是压栈,释放空间其实就是弹栈,压栈和弹栈的概念在第1章有详细介绍。