/*********************************************************** * * * C程序内存布局 * * * *********************************************************** *(高地址空间) * --------------------------------- * - 命令行参数区 - (命令行参数和环境变量) * --------------------------------- * - 堆区(Stack Area) - 局部变量 * - 栈区(Heap Area) - malloc动态分配数据 * --------------------------------- * - 数据区(Data Area)分为: - * - 未初始化静态变量区(.bss) - 没有初始化的全局变量和静态变量 * - 已初始化静态变量区(.data) - 初始化的全局变量和静态变量 * - 文字常量区(.rodata) - 常量字符串 * --------------------------------- * - 代码区(Code) - 二进制的代码 * --------------------------------- *(低地址空间) *Code,.rodata,.data在链接之后产生 *.bss在程序初始化的时候开辟 *stack,heap在程序运行中开辟和释放 *栈区:操作方式类似于数据结构中的栈,向地地址空间扩展 */ #include<stdio.h> #include<stdlib.h> #include <string.h> int g_var1; //BSS int g_var2 = 10; //DATA int main(int argc, int *argv[]) {//ARGC:STACK ARGV:STACK *ARGV:COMMAMD char arr[] = "hello"; //STACK char *ptr1 = "hello,world"; // PTR1:STACK, ptr1->RO_DATA, "hello,world":RO_DATA char *ptr2 = NULL; //PTR2:STACK int i = 0; static int s_var3; //BSS static int s_var4 = 100; //DATA const int var = 10; //VAR:STACK printf("COMMAND:*argv=%#lx ", *argv); printf("STACK:argv=%#lx,&argc=%#lx,&argv=%#lx ",argv,&argc,&argv); printf("STACK:&ptr1=%#lx, &ptr2=%#lx ", &ptr1,&ptr2); ptr2 = (char *)malloc(10);//PTR2->HEAP printf("HEAP:**argv=%#lx,ptr2=%#lx ", ptr2,**argv);
strcpy(ptr2, "haha"); //ptr2->HEAP "haha"在RO_DATA区,strcpy并不是简单的指针赋值
printf("HEAP: ptr2=%#lx
", ptr2);
printf("argv[0]=%s, argv[0]=%#lx ",argv[0],argv[0]); //arg[0] 是指向命令行参数区的
printf("BSS: &g_var1=%#lx, &s_var3=%#lx ", &g_var1,&s_var3); printf("DATA:&g_var2=%#lx, &s_var4%#lx ", &g_var2,&s_var4);
printf("RO_DATA: ptr1=%#lx
", ptr1); //ptr1指向"hello,world",指向RO_DATA
printf ("RO_DATA: "hello": %#lx, "hello,world": %#lx, "haha": %#lx
", "hello", "hello,world", "haha");
return 0; }/*------------End of main---------------*/
运行结果:
COMMAND:*argv=0x7fff2a4b8822
STACK:argv=0x7fff2a4b7a18,&argc=0x7fff2a4b78fc,&argv=0x7fff2a4b78f0
STACK:&ptr1=0x7fff2a4b7908, &ptr2=0x7fff2a4b7900
HEAP:**argv=0x164b010,ptr2=0x2e612f2e
argv[0]=./a.out, argv[0]=0x7fff2a4b8822
BSS: &g_var1=0x600b94, &s_var3=0x600b90
DATA:&g_var2=0x600b74, &s_var40x600b78
RO_DATA: ptr1=0x4007b8, ptr2=0x164b010
<1>当在执行一个可执行程序时,执行main()之前操作系统做的事
把可执行程序加载到相应的内存
bss区清零
命令行参数写到命令行参数区