6

我编辑了 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。请解释为什么会出现这种行为?

4

3 回答 3

12

首先,让我说,在现代操作系统中,您的程序看到的地址值(例如 0x00402000)不是物理地址。它们是虚拟地址,它们对拥有的进程是私有的(即在其他进程中没有意义或意味着其他东西),并且通过只有操作系统具有的基于 CPU 的机制(“分页单元”)映射到物理地址掌控。

如果你想在不同的进程之间共享一个变量,有一种叫做共享内存的机制。阅读它。相关 APICreateFileMapping的第一个参数是INVALID_HANDLE_VALUE, MapViewOfFile, OpenFileMapping。还有其他的进程间通信方式。

如果您想在没有该进程的显式合作的情况下读取进程的内存,则需要阅读调试 API。这比使用共享内存要复杂得多。

顺便说一句,您编写的代码是典型的未定义行为。

于 2013-08-20T13:17:41.693 回答
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”!这是因为操作系统对待每个地址空间都是一样的。因此,int无论名称如何,全局变量都可能分配到位置 0x004002000。

于 2013-08-20T21:03:41.203 回答
1

似乎是未定义的行为。因为用户的进程只被允许访问分配给它的内存。因此,当您尝试访问有关地址的内存时,您分配的地址无效,并且您遇到了未定义的行为。

于 2013-08-20T13:15:48.550 回答