一.理论讲解(针对32位操作系统)
-
内存具体分配
-
32位操作系统,每个操作系统都有2^32字节的虚拟地址空间,即4G的虚拟地址空间。这4G的虚拟地址空间分为两个大部分:每个进程独立的3G的用户空间(栈、堆、静态存储区、代码段),和所有进程共享的1G的内核空间。
-
图上呈现出来的内容的地址是逻辑地址(虚拟地址),若要对应真正内存中物理地址,需要使用MMU(内存管理单元,可将逻辑地址映射为物理地址),利用分页式、分段式存储方式的运算进行转化。
-
栈区
- 是存放函数调用时临时信息的结构,包括函数调用时传递参数,函数返回地址,函数局部变量
- 存放自动变量(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;
}