[英]Accessing struct member by address
考慮具有兩個整數類型成員的結構。 我希望通過地址獲得兩位成員。 我可以成功獲得第一個,但是我的第二個錯誤。 我相信這是垃圾價值。 這是我的代碼:
#include <stdio.h>
typedef struct { int a; int b; } foo_t;
int main(int argc, char **argv)
{
foo_t f;
f.a = 2;
f.b = 4;
int a = ((int)(*(int*) &f));
int b = ((int)(*(((int*)(&f + sizeof(int))))));
printf("%d ..%d\n", a, b);
return 0;
}
我越來越:
2 ..1
誰能解釋我哪里出錯了?
根據C標准,第一個成員的偏移量必須始終為零; 這就是你的第一次演員工作的原因。 然而,由於填充,第二構件的偏移可能不一定等於結構的第一構件的尺寸。
此外,向指針添加數字不會向地址添加字節數:而是添加指向的事物的大小。 因此,當您將sizeof(int)
添加到&f
,會添加sizeof(int)*sizeof(foo_t)
。
如果你想自己做數學,你可以使用offsetof
運算符,就像這樣
int b = *((int*)(((char*)&f)+offsetof(foo_t, b)));
這樣做的原因是sizeof(char)
總是一個,正如C標准所要求的那樣。
當然你可以使用&f.b
來避免手動進行數學運算。
你的問題是&f + sizeof(int)
。 如果A
是指針,並且B
是整數,那么A + B
在C中不表示A
加B
字節。 相反,它意味着A
加B
元素,其中元素的大小由A
的指針類型定義。 因此,如果您的體系結構中sizeof(int)
為4,則&f + sizeof(int)
表示“四個foo_t
s進入&f
,或者4 * 8 = 32個字節進入&f
”。
請嘗試((char *)&f) + sizeof(int)
。
或者,當然, &f.a
和&f.b
相反,非常簡單。 后者不僅會為你提供方便的int
指針,而且會讓你免除所有這些演員陣容,同時也能明確定義和理解。 :)
表達式&f + sizeof(int)
將數字添加到foo_t*
類型的指針中。 指針算術始終假定指針指向數組的元素,並將該數字視為元素計數。
因此,如果sizeof(int)
為4,則&f + sizeof(int)
四個foo_t
結構指向f
,或者在&f
之后4*sizeof(foo_t)
個字節。
如果必須使用字節計數,這樣的事情可能會起作用:
int b = *(int*)((char*)(&f) + sizeof(int));
...假設成員a
和b
之間沒有填充。
但是,有沒有理由你不只是獲得值fb
或指針&f.b
?
你可以做&f.b
,並跳過實際的指針數學。
以下是我將如何更改int b
行:
int b = (int)(*(((int*)(&(f.b)))));
順便說一句,當我按原樣運行你的程序時,我得到2 ..0
作為輸出。
這有效:
int b = ((int)(*(int*)((int)&f + sizeof(int))));
你將&f解釋為指針,當你向它添加4(int的大小)時,它會將它解釋為添加4個指針,這些指針是16或32個字節,具體取決於32對64拱。 如果將指針強制轉換為int,則會正確地向其添加4個字節。
這是對正在發生的事情的解釋。 我不確定你在做什么,但你肯定不應該這樣做。 這可能會讓您在對齊等方面遇到麻煩。找出struct元素偏移量的安全方法是:
printf("%d\n", &(((foo_t *)NULL)->b));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.