转换为 int 或其他类型的某些内存地址的十六进制值的大小是多少?

Posted

技术标签:

【中文标题】转换为 int 或其他类型的某些内存地址的十六进制值的大小是多少?【英文标题】:what's the size of hex value of some memory address converted to int or other type? 【发布时间】:2012-01-05 02:52:00 【问题描述】:

例如:

int* x = new int;
int y = reinterpret_cast<int>(x);

y 现在保存变量x 的内存地址的整数值。 变量y 的大小为intint 的大小是否总是足够大以存储转换为 int 的 ANY TYPE 的转换后内存地址?

编辑: 还是使用long int 来避免可能的数据丢失更安全?

编辑 2:对不起,为了让这个问题更容易理解,我想在这里找出返回的 HEX 值的大小作为数字,而不是 int 的大小或指针的大小int 但普通的十六进制值。我需要以人类可读的符号表示该值。这就是为什么我使用reinterpret_cast 将该内存 HEX 值转换为 DEC 值的原因。但是为了安全地存储值,我还需要找出它的变量类型:int、long - 什么类型足够大?

【问题讨论】:

使用 size_t 或更正确 - uintptr_t 来匹配指针大小。 我认为你不明白“十六进制值”是什么意思。没有“内存 HEX 值”之类的东西。你有一个指针。它由若干位组成。您可以根据自己的喜好以文本方式表示,但这与您发布的代码无关。 @Brian Roach,也许我不明白,但内存地址看起来像 0x0f3a89bb,这不是 HEX 值吗?每个对象都有它的唯一内存地址。那么如何看待“没有“内存 HEX 值”之类的东西?谢谢。 @codekiddy - 是的,这是一个十六进制数字。无论您使用什么来查看将一堆位(一个值)转换为十六进制文本表示并显示给您。如果这是您需要的,您也需要这样做。计算机没有十六进制的概念;它们以二进制运行。 【参考方案1】:

不,这不安全。没有保证sizeof(int) == sizeof(int*)

在 64 位平台上,您几乎可以肯定它不是。

至于“十六进制值”......我不确定你在说什么。如果你在谈论十六进制指针的文本表示......你需要一个字符串。

编辑以尝试帮助基于 cmets 的 OP:

因为计算机不能以十六进制运行。我不知道还能怎么解释。 int 存储一定数量的位(二进制),long 也是如此。十六进制是这些位的文本表示(特别是 base16 表示)。字符串用于值的文本表示。如果您需要指针的十六进制表示,则需要将该指针转换为文本(十六进制)。

这是一个 c++ 示例,说明您将如何做到这一点:

test.cpp

#include <string>
#include <iostream>
#include <sstream>

int main()


    int *p; // declare a pointer to an int. 
    std::ostringstream oss; // create a stringstream
    std::string s; // create a string

    // this takes the value of p (the memory address), converts it to 
    // the hexadecimal textual representation, and puts it in the stream
    oss << std::hex << p;

    // Get a std::string from the stream
    s = oss.str();

    // Display the string
    std::cout << s << std::endl;


示例输出:

roach$ g++ -o test test.cpp roach$ ./test 0x7fff68e07730

值得注意的是,当您想要查看数字的 base10(十进制)表示时,需要同样的操作 - 您必须将其转换为字符串。内存中的所有内容都存储在二进制(base2)中

【讨论】:

+1 来自我。从 OP 的最新编辑来看,他显然仍然不清楚物理数据存储和 POD 整数的文本表示之间的区别。 是的,这也是我的怀疑。 @Brian,你说我需要一个字符串来存储指针的十六进制表示......为什么是字符串?,int 或 lon 有什么问题,只要我在我的问题中打算这样做?非常感谢。【参考方案2】:

在大多数 64 位目标上,int 仍然是 32 位,而指针是 64 位,所以它不起作用。

http://en.wikipedia.org/wiki/64-bit#64-bit_data_models

【讨论】:

谢谢,但是转换后的内存 HEX 值的大小是多少? int 的大小是否足以存储转换后的十六进制内存值? 不,您不应该依赖 int 能够保存指针值。我认为你会安全地使用 long long,或者最好只是 size_t。根据内存,它可以在某些系统上运行,但不能在 64 位 Linux 或 Windows 上运行。使用 cout 检查您的系统 @codekiddy:为什么是十六进制?因为您的调试器将其显示为十六进制?无论如何,十六进制与否,这完全无关紧要。 x 是一个指针值。正如其他人已经指出的那样,它可能不适合int。它甚至可能不适合long。它将适合uintptr_t。如果你的编译器不支持uintptr_t,那么最好的选择是size_t @codekiddy:但没有十六进制值。只有一个值。如何打印或保存到文件(二进制、八进制、十进制、十六进制或其他)完全独立于值本身。如果您希望它在某处看起来像十六进制,则必须将值实际转换为包含构成/表示该值的十六进制数字的字符串。 @codekiddy:它可以被表示为某物的事实并不意味着它已经被表示为该某物。 C(++) 中所有不同的对象都有唯一的地址,这是真的(我们不是在谈论通过引用或联合变量进行别名)。【参考方案3】:

您可能想要使用std::ostream 的地址格式:

int x(0);
std::cout << &x << '\n';

至于生成的字符串的长度,您需要确定相应指针的大小:对于每个使用的字节,输出将使用两个十六进制数字,因为每个十六进制数字可以表示 16 个值。即使您不太可能拥有所有字节的内存,通常也会使用所有字节,例如当指针的大小为 8 字节时,就像在 64 位系统上发生的那样。这是因为堆栈通常从最大地址向下增长,而可执行代码从地址范围的开头开始(好吧,如果以任何方式触摸第一页,可能会导致分段违规)。可执行代码上方是一些数据段,然后是堆,以及许多未使用的页面。

【讨论】:

【参考方案4】:

有一个关于类似主题的问题:

https://***.com/a/2369593/1010666

总结:不要试图将指针写入非指针变量。 如果需要打印出指针值,还有其他解决方案。

【讨论】:

以上是关于转换为 int 或其他类型的某些内存地址的十六进制值的大小是多少?的主要内容,如果未能解决你的问题,请参考以下文章

c语言类型转换

指针与强制类型转换

如何将string类型的数字转换成int

python各数据类型及内置方式:

在python中写入内存中的特定地址

float型怎样强制转换成int型