stddef offsetof
offsetof 说明
在c标准的stddef.h中有一个获取c/c++结构或者类成员偏移量的宏offsetof,具体定义如下:
#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
参数说明:
s: 结构体类型
m: 是结构体数据成员名称
思想就是将地址0强制转换成类型s,然后通过求结构体数据成员地址的方式,获取偏移量。
C程序的例子:
#include <stdio.h>
struct A{int a1; int a2;
};
main()
{struct A a, *pa;a.a1=22;a.a2=33;pa = &a; // Print the address of the data member of variable aprintf("By variable a &a(%p) &a.a1(%p) &a.a2(%p) \n", &a, &a.a1, &a.a2);// Print the address of the data member of the pointer pa. The pa point to the variable a.printf("By pointer pa &a(%p) &pa->a1(0x%lx) &pa->a2(0x%lx)\n", &a, (size_t)&pa->a1, (size_t)&pa->a2);struct A *s=(struct A*)0;// Print the address of the data member of the pointer s. The s point to 0.printf("By pointer s &s->a1(%ld) &s->a2(%ld)\n", (size_t)&s->a1, (size_t)&s->a2);// Change s point to 100.s = (struct A*)100;printf("By pointer s &s->a1(%ld) &s->a2(%ld)\n", (size_t)&s->a1, (size_t)&s->a2);// First deference the pointer s, then get the address of the data memeber. printf("By pointer s &(*s).a1(%ld) &(*s).a2(%ld)\n", (size_t)&(*s).a1, (size_t)&(*s).a2);// Dangerous? Deference the pointer s, the get value of the data member.// printf("By pointer s (*s).a1(%d) (*s).a2(%d)\n", (*s).a1, (*s).a2);
}
执行结果:
By variable a &a(0x7fff5e0bae60) &a.a1(0x7fff5e0bae60) &a.a2(0x7fff5e0bae64)
By pointer pa &a(0x7fff5e0bae60) &pa->a1(0x7fff5e0bae60) &pa->a2(0x7fff5e0bae64)
By pointer s &s->a1(0) &s->a2(4)
By pointer s &s->a1(100) &s->a2(104)
By pointer s &(*s).a1(100) &(*s).a2(104)
从执行结果可以得出这样的结论:
1、对结构体数据成员取地址,是以结构体变量首地址为基础的。
2、获取数据成员的地址运算是指针运算,不管地址是合法的还是非法的,都可以。
因为这只是地址运算,不会操作地址所指向的 内存。
3、如果我们把地址设为0,那么对数据成员取地址,就可以获取偏移量了。
C++例子
我们将上面的例子简单修改一下,增加一个virtual 成员函数,看看效果:
#include <stdio.h>
struct A{virtual ~A(){}int a1; int a2;
};
main()
{struct A a, *pa;a.a1=22;a.a2=33;pa = &a; // Print the address of the data member of variable aprintf("By variable a &a(%p) &a.a1(%p) &a.a2(%p) \n", &a, &a.a1, &a.a2);// Print the address of the data member of the pointer pa. The pa point to the variable a.printf("By pointer pa &a(%p) &pa->a1(0x%lx) &pa->a2(0x%lx)\n", &a, (size_t)&pa->a1, (size_t)&pa->a2);struct A *s=(struct A*)0;// Print the address of the data member of the pointer s. The s point to 0.printf("By pointer s &s->a1(%ld) &s->a2(%ld)\n", (size_t)&s->a1, (size_t)&s->a2);// Change s point to 100.s = (struct A*)100;printf("By pointer s &s->a1(%ld) &s->a2(%ld)\n", (size_t)&s->a1, (size_t)&s->a2);// First deference the pointer s, then get the address of the data memeber. printf("By pointer s &(*s).a1(%ld) &(*s).a2(%ld)\n", (size_t)&(*s).a1, (size_t)&(*s).a2);// Dangerous? Deference the pointer s, the get value of the data member.// printf("By pointer s (*s).a1(%d) (*s).a2(%d)\n", (*s).a1, (*s).a2);
}
执行结果:
By variable a &a(0x7fffd686f520) &a.a1(0x7fffd686f528) &a.a2(0x7fffd686f52c)
By pointer pa &a(0x7fffd686f520) &pa->a1(0x7fffd686f528) &pa->a2(0x7fffd686f52c)
By pointer s &s->a1(8) &s->a2(12)
By pointer s &s->a1(108) &s->a2(112)
By pointer s &(*s).a1(108) &(*s).a2(112)
首个数据成员的偏移量是8,原因是因为有了vptr指针。
stddef offsetof相关推荐
- offsetof使用小结
先上例子 #include <stdio.h> #include <stdlib.h>/* offsetof example */ #include <stddef.h& ...
- 【C语言】宏offsetof的模拟实现 (计算结构体中某变量相对于首地址的偏移)
首先我们应该特别留意 : offsetof 是一个宏,并非是一个函数 ! 宏offsetof的介绍 : 参数:第一个是结构体类型名称,第二个是结构体成员名 返回类型:size_t无符号整形 引用的头文 ...
- c语言 offsetof函数,C 库宏 - offsetof()函数
宏offsetof 标准库stddef.h 定义 size_t offsetof(type, member); 分析 C 库宏 offsetof(type, member) 会生成一个类型为 size ...
- container_of 和 offsetof 宏详解
在linux内核链表中,会遇到两个宏. 在include/linux/stddef.h中,有这样的定义 #define offsetof(TYPE, MEMBER) ((size_t) &(( ...
- Linux / offsetof 和 container_of
@time 2019-07-10 @author Ruo_Xiao @revision linux 2.6.11 1. offsetof (1)原型 /** @member TYPE : 结构体原型. ...
- 自己实现了一个C语言例程,加深对宏、大小端、typeof宏、offsetof宏、指针变量、结构体、联合体的理解
如题所述,最近时间在复习C语言.自己实现了一个C语言例程,以加深对宏.大小端.typeof宏.offsetof宏.指针变量.结构体.联合体的理解.关于细分知识后续有空再填充- swap宏的使用: 对应 ...
- C库宏-offsetof()
在项目开发过程中,发现了offsetof()函数,随即查询了此函数,摘录如下: C库宏 - offsetof() 描述 C库宏offsetof(type, member-designator)会生成一 ...
- 使用offsetof对结构体指针偏移操作
题目来自于COMP20003 Tutorial 2: Program m ing Challenge 2.2 The technology stack at Hidebound Inc. uses a ...
- sizeof与offsetof有关的结构体详解
sizeof与offsetof在程序中经常遇到,但在面试中其应用使得许多小伙伴吃闭门羹,被面试官问得哑口无言.接下来对两者的应用做详细介绍. 关于sizeof 定义 sizeof乃C/C++中的一个操 ...
最新文章
- 为x86 CPU自动调度神经网络
- mysql 数据索引使用_mysql数据库正确建立索引及使用
- eclipse中设置python的版本
- 数据结构和算法分析:第四章 树
- 读书笔记∣世界是数字的
- 自动化通讯协定——现场总线
- 自动化测试基础篇--Selenium等待时间
- Centos系统新建文本文档.txt
- winrar加密分析
- 用foobar将ape转换为mp3格式
- 怎样找回通讯录的联系人号码?手机通信录联系人恢复教程推荐
- 2021玉林芳草中学高考成绩查询,「分数线」2020年成都玉林中学招生录取分数线...
- ps 修改透明图片上的文字,修改图片大小,导出PNG
- 计蒜客T3054数列
- C++详细学习笔记(二)
- 中国奥运在线流量的数据所做的总结性结案报告
- Prometheus 简介
- 你了解视频 API 吗?
- mysql数据库数据的删除与恢复
- 2017中国工业互联网大会召开
热门文章
- 计算机专业应聘人事专员,hr人事专员面试经验 - 共203条真实hr人事专员面试经验分享 - 职业圈...
- 2021年中式烹调师(高级)考试总结及中式烹调师(高级)模拟考试
- Scriptlet的3种模式
- 爬虫实战——网页抓取及信息提取
- mysqltruncate函数
- 冰箱“扩容”的战事,在今夏格外猛烈
- 英雄联盟的小案例理解Java中如何实现OCP原则
- Qt5官方demo解析集13——Qt Quick Particles Examples - Image Particles
- button 设置圆角
- 信噪比概念及噪声来源