如何获取结构体某成员的偏移地址
来源:互联网 发布:淘宝一键好复制怎么用 编辑:程序博客网 时间:2024/04/29 03:18
我们假设结构体定义如下所示:
- #include <stdio.h>
- #include <stdlib.h>
- struct test_s
- {
- int pad1;
- int pad2;
- int pad3;
- int pad4;
- int pad5;
- };
思路1: 非常简单,直接用地址差值即可求得。
- int main(int argc, char *argv[])
- {
- struct test_s sss;
- struct test_s *t = &sss;
- printf("%d\n", (int)&(t->pad2));
- return 0;
- }
思路2: 考虑宏定义的实现。(最佳思路!)
ANSI C标准允许任何值为0的常量被强制转换成任何一种类型的指针,并且转换结果是一个NULL指针,因此( (test_s*)0 )的结果就是一个类型为test_s*的NULL指针。如果利用这个NULL指针来访问s的成员当然是非法的,但&(((test_s*)0)->m)的意图并非想存取test_s字段内容,而仅仅是计算当结构体实例的首址为((s*)0)时m字段的地址。聪明的编译器根本就不生成访问m的代码,而仅仅是根据test_s的内存布局和结构体实例首址在编译期计算这个(常量)地址,这样就完全避免了通过NULL指针访问内存的问题。
- #define OFFSET(Type, member) (size_t)&( ((Type*)0)->member) )
如上做法避免了一定要实例化一个结构体对象,并且求值是在编译期进行,没有运行期负担。因此是该问题的首选方案。
- int main(int argc, char *argv[])
- {
- size_t offset = OFFSET(test_s, pad4);
- return 0
- }
实际上这种利用编译器掌握的整个程序的信息以在编译期计算某些值的方法与现在C++编程中很流行的(静态)元编程技术类似,只不过C++程序员可以利用模板技术在编译期完成非常复杂的计算,而缺乏模板支持的 ANSI C在这方面的能力则要弱许多。
C++ 的实现:
- /* Define offsetof macro */
- #ifdef __cplusplus
- #ifdef _WIN64
- #define offsetof(s,m) (size_t)( (ptrdiff_t)&reinterpret_cast<const volatile char&>((((s *)0)->m)) )
- #else
- #define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
- #endif
- #else
- #ifdef _WIN64
- #define offsetof(s,m) (size_t)( (ptrdiff_t)&(((s *)0)->m) )
- #else
- #define offsetof(s,m) (size_t)&(((s *)0)->m)
- #endif
- #endif /* __cplusplus */
0 0
- 如何获取结构体某成员的偏移地址
- 如何获取结构体某成员的偏移地址
- 如何获取结构体某成员的偏移地址
- 结构体成员偏移地址
- 获取结构体某成员偏移
- 如何求结构体成员的偏移地址 || 结构体的 sizeof 总结
- 结构体成员地址在结构体内的偏移
- 计算结构体成员偏移地址的一种方法
- 计算结构体成员地址偏移量...
- 使用宏定义来获取一个结构体成员相对于该结构体首地址的偏移量
- 如何求出结构体的成员变量的偏移量
- (记录)如何取结构体中成员的偏移
- 如何通过结构体成员的地址获取结构体变量的地址?
- C++如何获取类成员的偏移
- 获取成员变量的地址和偏移地址
- 如何使用宏求结构体的内存偏移地址
- 如何取得结构变量的偏移地址
- 得到结构体中成员的偏移
- 尹成老师,关于链表的一些操作(C)
- BPMN使用工具
- bootstrap分页
- FKJAVA读书笔记--第八章--JAVA集合
- JVM(3)对象A和B循环引用,最后会不会不被GC回收?-------关于Java的GC机制
- 如何获取结构体某成员的偏移地址
- LeetCode - Valid Sudoku
- Sublime Text3取消自动检查更新
- 【万里征程——Windows App开发】编辑文本及键盘输入
- C/C++ 面试题 关键字篇
- ssh框架的学习之strut2环境搭建(1)
- 你的代码有多少血液可以流淌
- 网络基础 代理和网关
- windows7 64位下配置mysql64位免安装版