假设一下代码命名为main.c
#include <stdio.h>
#include <stblib.h>
int g1 = 30; //存放在.data 数据段
int g2; //.bss 数据段
char s[1000]; //.bss
int main() //.text 代码段
{
int a = 100; //stack 栈
int *p = malloc(20); //heap 堆
static int b = 20; //.data 数据段
static int c; //.bss
printf("hello"); //使用此函数时,先将"hello"字符串从/
常量区(.rodata)读出,再发送到标准I/O缓冲区
最后通过内核输出到屏幕
sleep(1);
printf("\n");
return 0;
}
在LINUX下 执行 gcc main.c -o main
生成一个可执行的二进制文件(ELF)main
在这个ELF文件中存在了以下文件(不完整)
.bss .data .rodata .text .init
当我们执行./main时
就会将上述文件加载到内存中
内存中有以下部分(不完整)
.init 用于启动代码,调用main函数,并传入argc,argv参数
.text 代码段
.rodata 只读数据(常量区),比如 100,3.14,‘w’,“hello”
.data 已经初始化的静态数据(全局变量和static 声明的局部变量)
.bss 未初始化的静态数据
标准I/O缓冲区
运行栈:保存局部变量和形参,每调用一个函数就会相应的产生数据存放到栈中,函数结束时就会释放函数中的局部变量
运行堆:程序员自主操控的内存,自定义生命周期,malloc()/calloc()/realloc()