通过结构体某个成员的地址计算结构体首地址 (转)
最近在CU論壇上有很多人在問(wèn)這樣一個(gè)問(wèn)題:給出一個(gè)結(jié)構(gòu)體成員的地址計(jì)算該結(jié)構(gòu)體的起始地址。其實(shí)這個(gè)題我之前也沒(méi)有接觸過(guò),據(jù)說(shuō)內(nèi)核代碼中有這樣用的,但還沒(méi)有看到。不過(guò)覺(jué)得這個(gè)題的解決方法還是有一定技巧的,就總結(jié)一下。下面是實(shí)現(xiàn)的代碼。
?
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define STRUCT_OFFSET(stru_name, element) (unsigned long)&((struct stru_name*)0)->element 4 struct stru_addr 5 { 6 int a; 7 char b; 8 int d; 9 char c; 10 11 }; 12 13 int main() 14 { 15 struct stru_addr s; 16 unsigned long offset = 0; 17 printf("start addr of s = %x\n", &s.a); 18 19 offset = STRUCT_OFFSET(stru_addr, c); 20 21 printf("c_addr = %x, offset = %u\n", &s.c, offset); 22 printf("start addr of s caculated from c addr: %x\n", (char *)&s.c - offset); 23 system("pause"); 24 return 0; 25 }?
?
?
其實(shí)整個(gè)程序中最關(guān)鍵的部分就是如何求出結(jié)構(gòu)體中某個(gè)成員相對(duì)于結(jié)構(gòu)體首地址的偏移量。這里的解決方法是:假設(shè)存在一個(gè)虛擬地址0,將該地址強(qiáng)制轉(zhuǎn)換成為該結(jié)構(gòu)體指針類型(struct stru_name*)0。那么地址0開(kāi)始到sizeof(struct)-1長(zhǎng)度的內(nèi)存區(qū)域就可以視為一個(gè)結(jié)構(gòu)體的內(nèi)存。這樣結(jié)構(gòu)體中任何一個(gè)元素都可以通過(guò)對(duì)該結(jié)構(gòu)體指針解引用得到。由于該結(jié)構(gòu)體的起始地址為0, 因此任何一個(gè)成員的地址應(yīng)該等于其相對(duì)于結(jié)構(gòu)體起始地址的偏移,這也就是計(jì)算偏移量的方法:(unsigned long)&((struct?stru_name*)0)->element。
上面程序執(zhí)行的結(jié)果如下:
上述的結(jié)果中還同時(shí)考慮了結(jié)構(gòu)體內(nèi)的對(duì)齊問(wèn)題。
原文地址:http://blog.chinaunix.net/uid-10167808-id-25940.html
轉(zhuǎn)載于:https://www.cnblogs.com/challenge1230/p/4383012.html
總結(jié)
以上是生活随笔為你收集整理的通过结构体某个成员的地址计算结构体首地址 (转)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Register-SPWorkflowS
- 下一篇: 四则运算升级版