C程序地址空间-创新互联
目录
为静海等地区用户提供了全套网页设计制作服务,及静海网站建设行业解决方案。主营业务为成都网站建设、网站设计、静海网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!1.地址空间分布
2.各区域内容
3.验证地址空间排布
1.地址空间分布
在C语言中,每个C程序加载进内存时,操作系统都会给它分配虚拟地址空间,一般大小为4G,地址空间分布情况如下:
2.各区域内容从上到下分别为代码区,字符常量区,已初始化全局变量区,未初始化全局变量区,堆区和栈区 ,其中堆栈相对而生。
注:C程序地址空间不是内存,本质上是虚拟地址。
下面是各个区域的名称以及所存放的内容(地址由低到高):
地址空间区域 | 内容 |
栈区 | 局部变量,函数所形成的栈帧 |
堆区 | malloc,realloc等所申请的动态空间 |
未初始化全局变量区 | 未初始化的全局变量,static修饰的变量 |
已初始化全局变量区 | 已初始化的全局变量,static修饰的变量 |
字符常量区 | 字符串常量 |
代码区 | 代码(包括函数) |
我们可以根据每个区域存放的内容来定义多种数据类型,通过它们的地址来验证各区域的相对位置。(注:由于windows具有栈随机化保护的特性,得出的结果可能有所不同,因此我们将在Linux系统下进行验证。)
#include#includeint 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
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
名称栏目:C程序地址空间-创新互联
标题路径:http://hbruida.cn/article/copepi.html