在32位系统中,我们定义一个整型变量:
int n;
此时,我们确定了变量n的大小为4字节,但我们并没有告诉编译器,n在内存中存放的位置。
所以系统会以默认方式确定n的存放位置。
我们再回顾一下程序的编译过程:
.c——源代码
预处理 ↓ Pre-Processing
.i ——预编译文件
编译 ↓ Compiling
.s ——汇编文件
汇编 ↓ Assembling
.o ——目标文件(还未链接的二进制文件)
链接文件 ↓ Linking
可执行文件
当汇编完成后生成的后缀名为".o"的目标文件,包含了程序代码、定义的变量等,他们在链接后放在了不同的section中。
section:段,目标文件.o经过链接后,放在内存中的区域。
内存从低地址到高地址,以地址的范围区分出不同的段,简单框架如下:
1. 只读空间(代码段,只读数据段)
特点:只读不能写,一旦尝试修改就会出现段错误。内容:text 代码段,data 数据段,bss未初始化的数据段。
整个程序结束时释放内存,生命周期最长。
2. 数据段(代码段、只读数据段、全局数据空间)
程序执行之前占用的空间。
在函数中定义变量:
void fun(void)
{
int m;//在栈空间,函数返回后消失
static int n;//在全局数据空间(仍局部访问),函数返回后仍存在
}
3. 栈空间
运行时,函数内部使用的变量,函数一旦返回,立即释放,生命周期是函数内部。
4. 堆空间
运行时,可以自由管理分配和释放空间,生命周期是由程序员决定。
分配:
malloc();//一旦成功,返回分配好的地址,新地址的读取方法由程序员灵活把握。
char *p;//读取方式是单个读取
p = (char *)malloc();//注意:函数返回,p指向的空间还在,p消失
if(p == null)
{
//申请分配空间,如果没分配到,就报错
}
释放:
free(p);//申请和释放必须配对!!