通过结构体某个成员的地址计算结构体首地址
给出一个结构体成员的地址计算该结构体的起始地址,据说内核代码中有这样用的,但还没有看到。不过觉得这个题的解决方法还是有一定技巧的,就总结一下。下面是实现的代码。
/* 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
上述的结果中还同时考虑了结构体内的对齐问题。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人