我们之前学过的空间布局大概是这样的
我们先看两段代码,然后比较结果
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 int g_val=0;
5
6 int main()
7 {
8 pid_t id=fork();
9 if(id<0)
10 {
11 perror("fork");
12 return 0;
13 }
14
15 else if(id==0){
16
17 printf("child[%d] : %d : %p\n",getpid(),g_val,&g_val);
18 }
19 else{
20
21 printf("parent[%d] : %d : %p\n",getpid(),g_val,&g_val);
22 }
23 sleep(1);
24 return 0;
25 }
记住这里的父进程和子进程的变量和地址一样的
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 int g_val=0;
5
6 int main()
7 {
8 pid_t id=fork();
9 if(id<0)
10 {
11 perror("fork");
12 return 0;
13 }
14
15 else if(id==0){
16 g_val=100;
17 printf("child[%d] : %d : %p\n",getpid(),g_val,&g_val);
18 }
19 else{
20 sleep(3);
21 printf("parent[%d] : %d : %p\n",getpid(),g_val,&g_val);
22 }
23 sleep(1);
24 return 0;
25 }
这里父进程和子进程的变量不一样,但是地址居然还是一样的
由此我们可以发现:
- 变量内容不一样,所以父子进程输出的变量绝对不是同一个变量
- 地址一样,说明,该地址不是物理地址
- 在Linux下,这种地址叫做虚拟地址
补充一点:我们在C/C++中看到的地址都是虚拟地址,物理地址用户是看不到的,由操作系统统一管理,操作系统必须负责将虚拟地址转化为物理地址
进程地址空间
分页&虚拟地址空间
上图就可以解释为什么地址相同,但变量不同,实际相同的是虚拟地址,变量内容不同实际是被映射到了物理地址不同的位置上