通過結構體某個成員的地址計算結構體首地址


給出一個結構體成員的地址計算該結構體的起始地址,據說內核代碼中有這樣用的,但還沒有看到。不過覺得這個題的解決方法還是有一定技巧的,就總結一下。下面是實現的代碼。 

/*
Author: Godbach
Date: Oct 23, 2008
*/
#include <stdio.h>
#define STRUCT_OFFSET(stru_name, element) (unsigned long)&((struct stru_name*)0)->element
struct stru_addr 
{
    int a;
    char b;
    int d;
    char c;

};

int main(void)
{
    struct stru_addr s;
    printf("start addr of s = %x\n", &s.a);
    
    unsigned long offset = STRUCT_OFFSET(stru_addr, c);

    printf("c_addr = %x, offset = %u\n", &s.c, offset);
    printf("start addr of s caculated from c addr: %x\n", (char *)&s.c - offset);
    return 0;
}

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

上面程序執行的結果如下:
[root@localhost tmp]# ./a.out
start addr of s = bf81b820
c_addr = bf81b82c, offset = 12
start addr of s caculated from c addr: bf81b820

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM