程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 通過結構體某個成員的地址計算結構體首地址 (轉),成員結構

通過結構體某個成員的地址計算結構體首地址 (轉),成員結構

編輯:關於C語言

通過結構體某個成員的地址計算結構體首地址 (轉),成員結構


最近在CU論壇上有很多人在問這樣一個問題:給出一個結構體成員的地址計算該結構體的起始地址。其實這個題我之前也沒有接觸過,據說內核代碼中有這樣用的,但還沒有看到。不過覺得這個題的解決方法還是有一定技巧的,就總結一下。下面是實現的代碼。

 1 /*
 2 Author: Godbach
 3 Date: Oct 23, 2008
 4 */
 5 #include <stdio.h>
 6 #define STRUCT_OFFSET(stru_name, element) (unsigned long)&((struct stru_name*)0)->element
 7 struct stru_addr 
 8 {
 9     int a;
10     char b;
11     int d;
12     char c;
13 
14 };
15 
16 int main(void)
17 {
18     struct stru_addr s;
19     printf("start addr of s = %x\n", &s.a);
20     
21     unsigned long offset = STRUCT_OFFSET(stru_addr, c);
22 
23     printf("c_addr = %x, offset = %u\n", &s.c, offset);
24     printf("start addr of s caculated from c addr: %x\n", (char *)&s.c - offset);
25     return 0;
26 }

其實整個程序中最關鍵的部分就是如何求出結構體中某個成員相對於結構體首地址的偏移量。這裡的解決方法是:假設存在一個虛擬地址0,將該地址強制轉換成為該結構體指針類型(struct stru_name*)0。那麼地址0開始到sizeof(struct)-1長度的內存區域就可以視為一個結構體的內存。這樣結構體中任何一個元素都可以通過對該結構體指針解引用得到。由於該結構體的起始地址為0, 因此任何一個成員的地址應該等於其相對於結構體起始地址的偏移,這也就是計算偏移量的方法:(unsigned long)&((struct stru_name*)0)->element。

上面程序執行的結果如下:

1 [root@localhost tmp]# ./a.out 
2 start addr of s = bf81b820
3 c_addr = bf81b82c, offset = 12
4 start addr of s caculated from c addr: bf81b820

上述的結果中還同時考慮了結構體內的對齊問題。

原文地址:http://blog.chinaunix.net/uid-10167808-id-25940.html

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved