验证进程地址空间的基本排布
【摘要】 本文中会介绍很多结构化的知识,我们会通过很多例子里的角色和场景来对一个概念进行定位和阐述,让大家有一个宏观的认识,之后再循序渐进的填充细节,如果你一上来就玩页表怎么映射,那么你可能连页表存在的价值是什么都不知道,最后也只是竹篮打水。 一、回顾与纠正C/C++ 内存布局这个概念比较重要,之前我们也涉及过 —— 我们在语言上定义的各种变量等在内存中的分布情况,如果没有听说过,那么你的 C/C++...
本文中会介绍很多结构化的知识,我们会通过很多例子里的角色和场景来对一个概念进行定位和阐述,让大家有一个宏观的认识,之后再循序渐进的填充细节,如果你一上来就玩页表怎么映射,那么你可能连页表存在的价值是什么都不知道,最后也只是竹篮打水。
一、回顾与纠正
C/C++ 内存布局这个概念比较重要,之前我们也涉及过 —— 我们在语言上定义的各种变量等在内存中的分布情况,如果没有听说过,那么你的 C/C++ 是不可能学好的。
上图表示的是内存吗 ❓
其实我们曾经说过的 C/C++ 内存布局,严格来说是错误的,从今天开始我们应该称之为C/C++ 进程地址空间
。为啥要故意说错呢,其实是因为方便理解,如果当时说 C/C++ 进程地址空间,那么不谈进程、地址、空间,就很容易误导大家。也就是说实际上要真正理解 C/C++ 的空间布局,光学习语言是远远不够的,还需要学习系统以及进程和内存之间的关系。
进程地址空间既然不是内存,那么栈、堆等这些空间的数据存储在哪 ???
进程地址空间,会在进程的整个生命周期一直存在,直到进程退出,这也就解释了为什么全局变量具有全局属性。其实这些数据最后一定会存储于内存,只不过进程地址空间是需要经过某种转换才到物理内存的。
二、 验证进程地址空间的基本排布
#include<stdio.h>
#include<stdlib.h>
int g_unval;
int g_val = 100;
int main(int argc, char* argv[], char* env[])
{
printf("code addr: %p\n", main);
const char* p = "hello bit!";
printf("read only: %p\n", p);
static int a = 5;
printf("static global val: %p\n", &a);
printf("global val: %p\n", &g_val);
printf("global uninit val: %p\n", &g_unval);
char* q1 = (char*)malloc(10);
char* q2 = (char*)malloc(10);
printf("heap addr: %p\n", q1);
printf("heap addr: %p\n", q2);
printf("p stack addr: %p\n", &p);
printf("q1 stack addr: %p\n", &q1);
printf("args addr: %p\n", argv[0]);
printf("args addr: %p\n", argv[argc - 1]);
printf("env addr: %p\n", env[0]);
return 0;
}
💨结果:
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)