首页 文章

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

提问于
浏览
0

在我的系统中,

sizeof(void*) = 8 bytes

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

我有这个结构

struct element{void* value};

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

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

也,

sizeof(double) = 8 bytes;

问题是如何获取任何指针的物理地址作为double值,然后将此值分配给任何其他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 *或任何其他指针类型?它的地址是......

2 回答

  • 0

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

    好 . 此信息是必需的,因为不可能将指针转换为具有任何有意义值的浮点数;浮点数将以任何方式具有无意义的 Value .

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

    Possibility 1:

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

    phy_address = (double)(uintptr_t)p;
    

    然而,由于气候风向标在他的评论中已经提到 double 值的精度有限 .

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

    Possibility 2:

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

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

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

    出于这个原因, cannot 是将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
    ...
    

    ......我得到了结果"not equal"虽然最后的检查说 ab 仍然包含相同的值!

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

    Conclusion

    我个人认为 never 使用浮点数据类型为"unique identifier" .

    在你的情况下,我会直接使用 void * 作为"unique identifier" . 如果这是不可能的,我会使用一些64位整数数据类型,如他的答案中已经建议的"Stuart" .

  • 1

    在大多数系统上,存在一个与 void * 大小相同的整数类型 . 通常这种类型是 intlong intlong long int . 大多数编译器将提供类型 intptr_t (及其未签名的表兄 uintptr_t ),它是这些类型之一的typedef . 我认为人们更喜欢使用 uintptr_t ,因为负地址值通常没有意义 . 无论如何你应该使用这种类型而不是double .

    请记住 uintptr_t 只是常规整数类型之一,因此一旦将指针值转换为此类型的变量,就可以执行任何您喜欢的整数运算 . 至于如何将指针值转换为uintptr_t,请参阅此问题/答案,Converting a non-void pointer to uintptr_t and vice-versa .

相关问题