【问题标题】:Strange address of a C variable in Mac OS XMac OS X中C变量的奇怪地址
【发布时间】:2018-07-12 12:40:35
【问题描述】:

给定以下 C 代码:

void *ptr;

ptr = malloc(100);

printf("Address: %p\n", ptr);

在 Ubuntu 64 位中使用 GCC 4.9 编译此代码并运行它时,输出类似于:

Address: 0x151ab10

0x151ab10 的值似乎是一个合理的数字,因为我的机器有 8 GB 的 RAM,但是当在 Mac OS X 64 位中使用 GCC 4.9 编译相同的代码并运行它时,它会给出类似这样的输出:

Address: 0x7fb9cb43ed30

...这很奇怪,因为0x7fb9cb43ed30 远高于 8 GB 的 RAM。在 Mac OS X 中是否需要进行某种位掩码才能打印出ptr 的真实地址?

【问题讨论】:

  • 我假设地址映射到虚拟内存中的某个位置。为什么你仍然需要“真实”地址?你打算用它做什么?
  • 在现代操作系统中,内存地址是虚拟的,所以你的地址绝对不是“奇怪的”。
  • 尝试同时运行其中两个程序(添加 sleep(666) 或 getchar() 以防止它们过早退出)。他们可以有相同的地址!
  • 那些操作系统上的 C 指针不是真实地址,它们是虚拟地址。 Linux 和 MacOS 分配用户空间的虚拟地址的方式不同,因此这些数字并不令人惊讶。相关:stackoverflow.com/questions/5203748/…

标签: c macos gcc


【解决方案1】:

当进程在通用操作系统中运行时,操作系统会在硬件的帮助下为每个进程构建一个“虚拟”地址空间。

每当具有虚拟地址空间的进程访问内存时,硬件使用硬件中的特殊寄存器和系统内存中的表将虚拟地址(在进程的地址空间中)转换为物理地址(在实际内存硬件中)描述应该如何进行转换。1操作系统为每个进程配置寄存器和表。

通常,操作系统或加载程序(将程序加载到内存中执行的软件)为各种目的分配不同范围的虚拟地址空间。它可以将堆栈放在一个位置,将可执行代码放在另一个位置,将可分配内存的通用空间放在另一个位置,将特殊系统数据放在另一个位置。这些地址可能来自人类设计者任意设置的基本位置,也可能来自各种计算,或这些的组合。

所以看到一个大的虚拟地址并不少见;它只是一个在虚构的地址空间中分配的位置。

脚注

1 将虚拟地址转换为物理地址还有其他复杂性。当处理器转换地址时,结果可能是所需位置根本不在物理内存中。发生这种情况时,处理器会通知操作系统。作为响应,操作系统可以分配一些物理内存,从磁盘读取必要的数据,更新进程的内存映射,使虚拟地址指向新分配的物理内存,并恢复进程的执行。然后您的过程可以继续,就好像数据一直都在那里一样。此外,当系统分配物理内存时,它可能必须通过将内存中的数据写入磁盘来使一些内存可用,并将其从某个进程的内存映射中删除(可能是同一个进程)。这样,磁盘空间就变成了辅助内​​存,进程可以在其虚拟地址空间中使用比实际物理内存中更多的内存来执行。

【讨论】:

    猜你喜欢
    • 2013-10-20
    • 2011-10-16
    • 1970-01-01
    • 2016-01-11
    • 2010-10-10
    • 2015-06-27
    • 2014-03-15
    • 1970-01-01
    相关资源
    最近更新 更多