Calculate the first address (forwarding) of a struct using the address of a member of the struct.
Recently, many people on the CU Forum asked the following question: give the address of a struct member to calculate the starting address of the struct. In fact, I have never touched this question before. It is said that the kernel code is used in this way, but I haven't seen it yet. However, I think there are some skills to solve this problem. Let's summarize it. The following is the implementation code.
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 }
In fact, the most important part of the entire program is how to find the offset of a member in the struct to the first address of the struct. The solution here is: Suppose there is a virtual address 0, which is forcibly converted to the struct pointer type (struct stru_name *) 0. The memory area starting from address 0 to sizeof (struct)-1 can be regarded as the memory of a struct. In this way, any element in the struct can be obtained by unreferencing the struct pointer. Since the starting address of the struct is 0, the address of any member should be equal to its offset relative to the starting address of the struct. This is the method for calculating the offset: (unsigned long) & (struct stru_name *) 0)-> element.
The execution result of the above program is as follows:
1 [root@localhost tmp]# ./a.out 2 start addr of s = bf81b8203 c_addr = bf81b82c, offset = 124 start addr of s caculated from c addr: bf81b820
The alignment problem in the structure body is also considered in the above results.
Address: http://blog.chinaunix.net/uid-10167808-id-25940.html