簡體   English   中英

按地址訪問struct成員

[英]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中不表示AB字節。 相反,它意味着AB元素,其中元素的大小由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));

...假設成員ab之間沒有填充。

但是,有沒有理由你不只是獲得值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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM