[英]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 *
相同。 通常,此類型為int
或long int
或long 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
...
...盡管最后的檢查顯示a
和b
仍然包含相同的值,但我得到的結果“不相等”!
根據您的環境,某些NaN值(所謂的“ signaling NaN”值)甚至可能導致程序崩潰!
結論
我個人絕不會將浮點數據類型用作“唯一標識符”。
在您的情況下,我將直接使用void *
作為“唯一標識符”。 如果這不可能,我將使用他的答案中已經建議的一些64位整數數據類型作為“ Stuart”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.