您怎么知道变量的确切地址?

问题描述 投票:5回答:7

因此,我正在浏览我的C编程教科书,并且看到了此代码。

#include <stdio.h>

int j, k;
int *ptr;

int main(void)
{
    j = 1;
    k = 2;
    ptr = &k;
    printf("\n");
    printf("j has the value %d and is stored at %p\n", j, (void *)&j);
    printf("k has the value %d and is stored at %p\n", k, (void *)&k);
    printf("ptr has the value %p and is stored at %p\n", (void *)ptr, (void *)&ptr);
    printf("The value of the integer pointed to by ptr is %d\n", *ptr);

    return 0;
}

我运行它,输出为:

j的值为1,并存储在0x4030e0k的值为2,并存储在0x403100

ptr的值为0x403100,并存储在0x4030f0

ptr指向的整数值为2

我的问题是,如果我没有通过编译器来运行它,仅通过看一下这段代码,您如何知道这些变量的地址?我只是不确定如何获取变量的实际地址。谢谢!

c pointers memory-address
7个回答
5
投票

这是我的理解:


5
投票

除了用“%p”打印变量外,没有其他方法可以“知道标准C中的变量的确切地址”。实际地址由不受程序员编写代码控制的许多因素决定。这取决于操作系统,链接器,编译器,使用的选项以及其他选项。


3
投票

您不能。


2
投票

编译器只知道诸如“第三个整数全局变量”和“从堆栈指针向下分配36个字节的四个字节”之类的信息。它仅以相对的术语引用全局变量,指向子例程(函数)的指针,子例程参数和局部变量。 (不用担心,对于C ++中的多态对象,多余的东西,别客气!)这些相对引用作为特殊代码和偏移值保存在对象文件(.o或.obj)中。


1
投票

我想通过指出某些编译器(例如Visual Studio)具有称为地址空间布局随机化(ASLR)的功能来进一步完善已经​​提供的答案,该功能使程序从随机存储器地址开始,以病毒功能。给定输出中具有的地址,我想说您不使用它进行编译(我认为不使用它的程序从地址0x400000开始)。此信息的来源是对this question的答复。


0
投票

继续上述回答,请不要忘记进程将在其自己的虚拟地址空间中运行(进程隔离)。这样可以确保当程序破坏某些内存时,其他正在运行的进程也不会受到影响。


0
投票

每个进程都有自己的逻辑地址空间,从零开始。您的程序可以访问的地址都相对于零。仅在将过程加载到主存储器中后,才能确定任何存储器位置的绝对地址。这是通过现代操作系统使用动态重定位完成的。因此,每次将进程加载到内存中时,都可以根据内存的可用性将其加载到不同的位置。因此,允许用户进程知道存储在内存中的数据的确切地址没有任何意义。您的代码输出的是逻辑地址,而不是确切的或物理的地址。

© www.soinside.com 2019 - 2024. All rights reserved.