簡體   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