一.理论讲解(针对32位操作系统)
-
内存具体分配
-
32位操作系统,每个操作系统都有2^32字节的虚拟地址空间,即4G的虚拟地址空间。这4G的虚拟地址空间分为两个大部分:每个进程独立的3G的用户空间(栈、堆、静态存储区、代码段),和所有进程共享的1G的内核空间。
-
图上呈现出来的内容的地址是逻辑地址(虚拟地址),若要对应真正内存中物理地址,需要使用MMU(内存管理单元,可将逻辑地址映射为物理地址),利用分页式、分段式存储方式的运算进行转化。
-
命令行参数
- int main(int argc,char* argv[])
- 命令行参数数据可改但一般不改
- char* argv[]实则退化为指针,可写成char**argv
- int argc值表示运行程序时命令行中参数数目,char* argv[]是一个指向字符串数组的指针,其中每个字符串对应一个参数
1 #include <stdio.h>
2 int main(int argc,char *argv[])
3 {
4 int i;
5 printf("argc = %d\n", argc); //验证argc是命令行数目
6
7 for(i = 1; i < argc; i++)
8 {
9 printf("argv [%d]=%s\n", i, argv[i]);//验证argv中储存是参数
10 }
11
12 return 0;
13 }
./a.out是启动该进程的程序名,是argv[0]
-
栈区
- 是存放函数调用时临时信息的结构,包括函数调用时传递参数,函数返回地址,函数局部变量
- 存放自动变量(int a = 3),用时自动申请,用完自动释放 -----各种类型变量,int,char,指针类型等
- 先进后出
-
堆区
-
静态存储区
- 静态存储区分为3个部分:bbs,rwdata,rodata
- bbs:存放未初始化的静态局部变量和未初始化的全局变量(也可以认为未初始化的全局变量放在rwdate中)
- rwdata(可读可写数据段):存放初始化后的全局变量(其实也可以认为存放全局变量,未初始化的全局变量其实被系统默认为初始化为0,与初始化为0的全局变量一样)、初始化后的静态局部变量、初始化后的静态全局变量
- rodata(只读数据段):存放字符串常量(但不止)
-
代码段text
- 只读,存放程序执行代码
二.代码验证
建议在Linux环境下运行
代码
#include <stdio.h>
int g_init = 100;
int g_uninit;
static int sg_init = 200;
static int sg_uninit;
void fun()
{
int l_init = 100;
int l_uninit;
static int sl_init = 200;
static int sl_uninit;
printf("l_init: %-8p\n", &l_init);//初始化局部变量
printf("l_uninit: %-8p\n", &l_uninit);//未初始化局部变量
printf("g_init: %-8p\n", &g_init);//初始化全局变量
printf("sg_init: %-8p\n", &sg_init);//初始化静态全局变量
printf("sg_uninit:%-8p\n", &sg_uninit);//未初始化静态全局变量
printf("g_uninit: %-8p\n", &g_uninit);//未初始化全局变量
printf("sl_init: %-8p\n", &sl_init);//初始化静态局部变量
printf("sl_uninit:%-8p\n", &sl_uninit);//未初始化静态局部变量
printf("rodata %-8p\n", "helloworld");//字符串常量
printf("text %-8p\n", fun);//函数代码段
}
int main()
{
fun();
return 0;
}