繁体   English   中英

如何获取C指针的物理地址作为值?

[英]How to get the Physical address of a C pointer as a value?

在我的系统中

sizeof(void*) = 8 bytes

所有指针类型的大小为8个字节。

我有这个结构

struct element{void* value};

所以这个结构是一个8字节的指针值。

由于所有类型的指针都有8个字节,因此我应该能够将任何类型的变量的物理地址分配给该void *值

也,

sizeof(double) = 8 bytes;

问题是如何获取任何指针的物理地址作为双精度值,然后将此值分配给任何其他8字节指针。

所以说,

int i;
int *p = &i;
struct element e;
double phy_address = ?? // the 8 byte value of p (when we print it as %d)

/*now copy this 8 byte phy_address to 8 byte void pointer e.value. */

是否可以将其转换为int *或任何其他指针类型? 它是一个地址...

在大多数系统上,有一个整数类型,其大小与void *相同。 通常,此类型为intlong intlong long int 大多数编译器都会提供intptr_t类型(及其无符号的表亲uintptr_t ),即这些类型之一的typedef。 我认为人们更喜欢使用uintptr_t因为负地址值通常没有意义。 无论如何,您可能应该使用此类型而不是double。

请记住, uintptr_t只是常规整数类型之一,因此一旦将指针值放入该类型的变量中,就可以执行任意喜欢的整数运算。 至于如何将指针值转换为uintptr_t,请参见以下问题/答案, 将非void指针转换为uintptr_t,反之亦然

我使用=这些值可以用作表中的唯一标识符。

好。 该信息是必需的,因为不可能将指针转换为具有任何有意义值的浮点数; 浮点数无论如何都将没有意义。

有两种将指针转换为(无意义的)浮点值的可能性,但是在两种情况下,都不能保证两个浮点数对于两个不同的指针是唯一的!

可能性1:

将指针转换为整数,并将整数转换为浮点数:

phy_address = (double)(uintptr_t)p;

但是,正如Weather Vane在其评论中已经提到的, double精度值的精度有限。

整数值(地址)12345678901234567 80和12345678901234567 90 将四舍五入为12345678901234567 68 .0。

可能性2:

因为double和指针均为64位宽,所以您可以生成一个与指针具有相同位的浮点数:

union {
    void *p;
    double d;
} u;
    ...
u.p = p;
phy_address = u.d;

但是,有一些数字(例如0 )在double数据类型中具有两种不同的表示形式。 这意味着将使用两种不同的位组合(因此,将使用两个不同的地址)来生成相同的数字。

因此, 没有任何方法可以将64位值转换为double精度值,从而导致唯一的double精度值:数据类型double不同值小于2 ^ 64!

更糟糕的是:

有特殊值-所谓的“ NaN”值。 而且有很多!

我只是做了以下测试:

// Write a "NaN" value to a
...
b = a;
if(a == b) puts("equal");
if(a != b) puts("not equal");
// Check if a and b still contain the same value
...

...尽管最后的检查显示ab仍然包含相同的值,但我得到的结果“不相等”!

根据您的环境,某些NaN值(所谓的“ signaling NaN”值)甚至可能导致程序崩溃!

结论

我个人绝不会将浮点数据类型用作“唯一标识符”。

在您的情况下,我将直接使用void *作为“唯一标识符”。 如果这不可能,我将使用他的答案中已经建议的一些64位整数数据类型作为“ Stuart”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM