【问题标题】:How to get the Physical address of a C pointer as a value?如何获取 C 指针的物理地址作为值?
【发布时间】:2017-12-28 21:52:45
【问题描述】:

在我的系统中,

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* 或任何其他指针类型?它只是一个地址...

【问题讨论】:

  • 评论不用于扩展讨论;这个对话是moved to chat
  • 你可以试试memcpy (&phy_address, &element.value, sizeof (void*))。但这很奇怪。
  • 1:“物理地址”是错误的词。虚拟地址或逻辑地址正确。 2. 我知道 Double 在这里不是很好的数据类型选择。只是一个字节数组呢?如何转换为 8 字节数组 - 无需太多中间转换的最快方法。

标签: c pointers


【解决方案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

【讨论】:

  • 好吧。请告诉我知道我的程序的任何进程允许的位置范围的最直接方法是什么。请告诉我这个
  • @NelsonakaSpOOKY:这值得另一个问题。
【解决方案2】:

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

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

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

可能性一:

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

phy_address = (double)(uintptr_t)p;

然而,正如 Weather Vane 在他的评论 double 中已经提到的那样,值的精度有限。

整数值(地址)1234567890123456780 和 1234567890123456790两者四舍五入为 1234567890123456768。 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 值(所谓的“信号 NaN”值)甚至可能导致您的程序崩溃!

结论

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

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

【讨论】:

  • 谢谢,我真的不想把它当成双份。我只想要 8 个字节。
猜你喜欢
  • 1970-01-01
  • 2017-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多