分区
在C语言中,内存被分为以下几个部分
.text 代码段,存放程序的可执行代码,不可修改
.rodata(Read Only Data) 常量区,存放全局常量
.data 数据段,存放已初始化的全局变量和静态变量
.bss(Block Started By Symbol) 未初始化数据段,存放未初始化的全局变量或者初始化为0的全局变量和静态变量
heap 堆区,在内存中总体从低地址向高地址增长,不一定是连续的,由程序员动态申请,在程序运行时才开辟内存空间
stack 栈区,在内存中由高地址向低地址增长,保存程序栈帧,栈帧里包含函数返回地址、函数参数、函数内部定义的变量
如下图:
解释
以下面这段代码为例:
#include<stdio.h>
#include<stdlib.h>char c1; //字符变量c1未被初始化,全局变量编译器默认初始化为空格,放入bss段中
char c2='a'; //字符变量c2被初始化为'a',放入data数据段中const int i1=1; //整形变量被const修饰,为常量,放入rodata只读数据段中int main(int argc, char const *argv[]){ //main函数及其调用的子函数的内部变量、参数、返回地址,在程序运行时动态放入栈区中int *ip=(int*)malloc(5*sizeof(int)); //这里是在运行时动态申请内存,申请的内存放在堆区中...
}//以上整个代码编译后的二进制数据,放入text代码区中
更复杂的情况如下,函数中一个字符串常量赋值给一个字符串数组,类似于下面代码:
int fun(){char s[]="Hero";...return 0;
}
字符串“Hero”是常量,放在在.rodata只读数据段里的,但是一个函数在被调用时会在栈区形成一个栈帧,它包含了函数内部定义的变量,所以字符数组s会在fun函数被调用时从.rodata里复制“Hero”到栈区中字符数组s的地址,“Hero”大小为5个字节(包含‘\0’),栈区中的字符数组s也是5个字节