C程序地址空间

目录

1.地址空间分布

2.各区域内容 

3.验证地址空间排布


1.地址空间分布

        在C语言中,每个C程序加载进内存时,操作系统都会给它分配虚拟地址空间,一般大小为4G,地址空间分布情况如下:

从上到下分别为代码区,字符常量区,已初始化全局变量区,未初始化全局变量区,堆区和栈区 ,其中堆栈相对而生


注:C程序地址空间不是内存,本质上是虚拟地址。

2.各区域内容 

         下面是各个区域的名称以及所存放的内容(地址由低到高):

地址空间区域内容
栈区局部变量,函数所形成的栈帧
堆区malloc,realloc等所申请的动态空间
未初始化全局变量区未初始化的全局变量,static修饰的变量
已初始化全局变量区已初始化的全局变量,static修饰的变量
字符常量区字符串常量
代码区代码(包括函数)

3.验证地址空间排布

        我们可以根据每个区域存放的内容来定义多种数据类型,通过它们的地址来验证各区域的相对位置。(注:由于windows具有栈随机化保护的特性,得出的结果可能有所不同,因此我们将在Linux系统下进行验证。)

#include<stdio.h>
#include<stdlib.h>
int g_val2;      //未初始化全局变量
int g_val1 = 10; //已初始化全局变量
int main()
{
	printf("code addr: %p\n", main);       //函数地址,代表代码区,函数是代码的一部分
	const char* str = "hello world";        //str存放字符串常量的首地址,指向字符常量区
	printf("read only: %p\n", str);        //字符常量区
	printf("init g_val: %p\n", &g_val1);    //已初始化全局变量区
	printf("uninit g_val: %p\n", &g_val2);  //未初始化全局变量区

	char* p = (char*)malloc(10 * sizeof(char));   //动态内存开辟,p指向堆区
	char* p1 = (char*)malloc(10 * sizeof(char));
	char* p2 = (char*)malloc(10 * sizeof(char));
	printf("head addr: %p\n", p);                //堆区
	printf("head addr: %p\n", p1);
	printf("head addr: %p\n", p2);
	printf("stack addr: %p\n", &str);            //栈区
	printf("stack addr: %p\n", &p);
	printf("stack addr: %p\n", &p1);
	printf("stack addr: %p\n", &p2);

	return 0;
}

在Linux系统运行结果如下:

        我们不难发现,各区域所在地址从上到下是呈递增的趋势的。所以地址从低到高分别是代码区,字符常量区,已初始化全局变量区,未初始化全局变量区,堆区和栈区,符合一开始的地址空间分布图。 


        对于堆区,我们定义了先后开辟的3个堆空间,并将地址保存在p,p1,p2中。通过p,p1,p2存放的地址呈递增趋势我们可以得出堆区的增长方向是从低地址向高地址增长的。


        对于栈区,由于变量str,p,p1,p2是在栈上先后开辟的,我们通过&取得它们的地址。根据打印的结果我们发现地址呈递减趋势可以得出栈区的增长方向是从高地址向低地址增长的。因此,堆栈相对而生


        值得注意的是,堆区和栈区的地址位数差了6位,说明两个区域之间有很大的镂空。


 以上,就是本期的全部内容。

制作不易,能否点个赞再走呢qwq

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忆梦初心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值