【问题标题】:How to know the virtual address of the data & code in C and C++? [closed]如何知道 C 和 C++ 中数据和代码的虚拟地址? [关闭]
【发布时间】:2016-09-04 03:35:44
【问题描述】:
  1. 如何获得程序中数据和代码的虚拟地址?

    有人可能会说使用%u%p 或其他东西。

    printf("%u", &data);
    printf("%p", &data);
    

    我总是很困惑;哪一个给出正确的地址?两者都提供地址,但有什么区别?

  2. 有什么方法可以判断给定虚拟地址属于内存的哪一部分?我们能确定它是堆栈地址还是堆地址或其他什么?

【问题讨论】:

  • 始终使用 %p 作为指针。指针和unsigned int 的大小并不总是相同。
  • 究竟是什么"p参数应该是一个指向void的指针。指针的值以实现定义的方式转换为一系列打印字符。 “你不明白吗? “u The unsigned int argument ...”有什么不清楚的地方?启用编译器警告并让您的代码在没有任何警告的情况下编译。
  • 而 C 甚至没有提到虚拟或物理地址。应用程序无需考虑这一点。
  • 每个问题一个问题,请。
  • 不要用 C 或 C++ 标签询问操作系统问题,否则你会被搁置。

标签: c++ c linux architecture operating-system


【解决方案1】:
  1. 您不能使用%u 说明符来打印指针。该说明符用于unsigned int%p 是正确的指针格式说明符。不同之处在于使用%u 在技术上是未定义的行为,因为参数的类型与所需的类型不同。此外,您必须将&data 转换为void*

  2. 的确,printf 位于 c++ 标准库中包含的 c 库部分中,因此您可以使用它。但是如果你更喜欢 c++ 流,那么你可以使用std::cout << &data;

  3. 这在标准 c++ 中是不可能的(在 c 中也是如此)。

在这两种标准中,都没有区分虚拟内存和物理内存。只有记忆。该内存的任何地址都由操作系统指定。如果程序不在使用虚拟内存的操作系统中运行,那么地址可能是物理的。

【讨论】:

  • 地址可能是各种鸡汤食谱,如果平台/操作系统使用的话。
【解决方案2】:

从您的其余问题来看,这表明您正在尝试使用 C++ 来识别在运行代码中不存在的教学概念。

如何获得程序中数据和代码的虚拟地址?

链接器将代码和数据组装成程序段。可以有多个程序段包含其中任何一个。但是,默认设置通常是每个都有一个。如果您想找到该信息,您需要创建一个链接器 MAP 文件作为程序构建的一部分并阅读它。

由于您想在代码中执行此操作,您需要编写一些东西来解析可执行文件的内容。

您的操作系统可能具有可用于检查页面的系统服务,以查看 (a) 它们是否有效以及 (b) 它们的属性是什么。从中您可以确定代码所在的位置。

我总是很困惑;哪一个给出正确的地址?两者都给出地址,但有什么区别?

%p 对于指针是正确的。 %u 对于无符号整数是正确的。在大多数系统上,它们实际上是相同的。但是,在某些情况下它们不是(即 sizeof (int) != sizeof (int*),或者指针具有与分段 intel 上一样的奇怪格式)。

使用 %p 作为指针。

我们如何在 C++ 中获得相同的虚拟地址详细信息? (既然是向下兼容C,我们可以用同样的东西,但是有没有其他办法呢?)

有什么方法可以判断给定虚拟地址属于内存的哪一部分?我们可以识别它是堆栈地址还是堆地址或其他什么?

记忆就是记忆。内存作为一种教学工具,经常用数据/堆/栈来描述。这在现实中是不存在的。堆和堆栈只是以不同方式管理的内存块。堆可以是堆栈。

【讨论】:

  • “在大多数系统上,它们实际上是相同的。” 这已经很多年了,不是吗? 64 位现在占主导地位(至少在消费市场上),但在现代 64 位平台上int 仍然倾向于 32 位。
【解决方案3】:

对于 (1) printf("%p", &data) 可用于打印指针地址,尽管您必须 编写 (void*)&data(C 标准参考 C11,7.21.6.1 p8),printf("%u", &data) 的行为是 undefined,因为格式说明符对于指针类型无效。但请注意,您看到的地址可能与物理地址没有任何对应关系;许多操作系统和运行时在物理地址和您看到的指针值之间放置了一层或两层抽象。

对于 (2),printf 调用在 C++ 中也有效。

对于 (3),C 和 C++ 标准(除了后者中的几个标准库函数)都没有 stackheap的概念>,所以,不,没有可移植的方式告诉。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-23
    • 2011-01-11
    • 2021-07-25
    • 1970-01-01
    • 2020-10-13
    • 1970-01-01
    • 2011-05-07
    相关资源
    最近更新 更多