我已经编辑了1.c,如下所示。
#include<stdio.h>
int x=100;
int main(void)
{
printf("%p",&x);
while(1);
return 0;
}
然后我打开命令提示符并运行该程序并在程序仍在运行时获得输出00402000。现在我运行2.c
#include<stdio.h>
int main(void)
{
int *p=(int *)0x00402000;
printf("%d",*p);
return 0;
}
在命令提示符的另一个实例中得到输出-1,我期望100位于00402000的位置。请解释为什么会出现这种情况?
答案 0 :(得分:11)
首先,我要说在现代操作系统中,程序看到的地址值(如0x00402000)不是物理地址。它们是虚拟地址,它们对拥有进程是私有的(即在其他进程中没有任何意义或意味着其他东西),并且通过基于CPU的机制(“寻呼单元”)映射到物理地址,只有操作系统具有控制。
如果要在不同进程之间共享变量,则有一种称为共享内存的机制。阅读它。相关API为CreateFileMapping
,第一个参数为INVALID_HANDLE_VALUE
,MapViewOfFile
,OpenFileMapping
。还有其他的进程间通信方式。
如果您想在没有该过程的情况下阅读进程'内存'显式合作,您需要阅读调试API。这比使用共享内存要复杂得多。
顺便说一下,你编码的是经典的未定义行为。
答案 1 :(得分:2)
要演示地址空间概念,请将您的第二个示例修改为:
#include<stdio.h>
int y = 101;
int main(void)
{
int *p=(int *)0x00402000; // hope this works??
printf("%d",*p);
printf("%p", p); // print value of p to ensure correct assignment
return 0;
}
它可能/可能打印“101”!!这是因为OS将每个地址空间视为相同。因此,int
的全局变量,无论其名称如何,都可能被分配到位置0x004002000。
答案 2 :(得分:1)
似乎是未定义的行为。由于用户的进程只允许访问已分配给它的内存。 因此,当您尝试访问有关地址的内存时,您分配的地址无效,并且您遇到了未定义的行为。