`

[C++] offsetof用法 - 计算成员地址的内存偏移量

    博客分类:
  • C++
 
阅读更多

转自:http://www.cppblog.com/lovedday/archive/2007/09/24/32801.html

offsetof宏解析


今天看代码时,发现一个有用的东东,offsetof(s,m),这是一个宏,MSDN文档的说明如下:

Retrieves the offset of a member from the beginning of its parent structure.

size_t offsetof(
structName,
memberName 
);


Parameters

structName 
Name of the parent data structure.


memberName 
Name of the member in the parent data structure for which to determine the offset.


Return Value


offsetof returns the offset in bytes of the specified member from the beginning of its parent data structure. It is undefined for bit fields.
 
Remarks

The offsetof macro returns the offset in bytes of memberName from the beginning of the structure specified by structName. You can specify types with the struct keyword.

Note 


offsetof is not a function and cannot be described using a C prototype.

跟踪代码发现定义如下:

#define offsetof(s,m) (size_t)&(((s *)0)->m)

然后到网上查了一下,发现还真的是很有用,附带一位大侠的解说:

struct AAA 

    int i; 
    int j; 
}; 

struct AAA *pAAA; 
pAAA=new AAA;


这时,pAAA实际上是一个Pointer, 指向某一确定的内存地址,比如0x1234; 
而 pAAA->i 整体是一个int型变量,其地址是&(pAAA->i) ,'&'为取址运算符; 
那么&(pAAA->i)一定等于0x1234,因为i是结构体AAA的第一个元素。 
而&(pAAA->j)一定是0x1234 + 0x4 = 0x1238; 因为sizeof(int) = 4;

这个做法的巧妙之处就是:它把“0”作为上例中的pAAA,那么 &(pAAA->j)就是j的offset啦。

解析结果是: 
(s *)0 ,将 0 强制转换为Pointer to "s" 
可以记 pS = (s *)0 ,pS是指向s的指针,它的值是0; 
那么pS->m就是m这个元素了,而&(pS->m)就是m的地址,而在本例中就是offset啦 

再把结果强制转换为size_t型的就OK 了,size_t其实也就是int啦!!

也就是说:

0 ---> (s *)0

原来的0是数值类型,现在是结构体指针类型,尽管类型变了,但其值还是不变,也就是说还是0,但这个值的意义变了,现在是地址,而不是数值。

&(((s *)0)->m)求出字段m的地址值,但由于首地址是0,所以&(((s *)0)->m)求出字段m相对于首地址的偏移值。

分享到:
评论

相关推荐

    获取类成员在类中的位移及大小

    在C++中,每个对象都有一个内存布局,成员变量在内存中占据一定的位置,这个位置相对于类对象起始地址的偏移量就是位移。而“大小”则指的是成员变量本身占用的字节数。 C++标准并没有提供直接获取成员位移的API,...

    C中sizeof()函数的精确解释

    1. **成员偏移量**:结构体中的每个成员都有一个相对于结构体起始地址的偏移量。这些偏移量必须满足成员数据类型的对齐要求。例如,`int`类型的成员通常要求其地址能被4整除。 2. **内部填充**:为了确保成员能够...

    深度剖析C语言结构体

    例如,在ST结构体中,offsetof(ST, id)将计算出id成员变量的偏移量,offsetof(ST, name)将计算出name成员变量的偏移量,以此类推。 6. 结构体的应用 结构体在实际应用中有非常广泛的使用场景,例如: * 实现复杂...

    后端面试题目的总结

    `offsetof`宏用于计算结构体中成员相对于结构体起始位置的偏移量。其定义如下: ```c #define offsetof(s, m) ((size_t)&(((s *)0)->m)) ``` 这里的`s`代表结构体类型,`m`是结构体中的成员。该宏利用指针算术计算...

    百度笔试题整理

    - `OFFSETOF`宏用于获取结构体内成员相对于结构体首地址的偏移量。 2. **引用与指针**: - 引用不能重新绑定,而指针可以改变指向。 - 引用是直接访问,指针是间接访问。 - 引用不分配内存,指针有内存空间。 ...

    C++中灵活数组结构的使用

    2. 方法2:利用偏移量计算并动态分配内存,如: ```cpp struct header* my_header = malloc(offsetof(struct header, data) + n * sizeof(my_header->data)); ``` 3. 方法3:使用指针,不节省一次间接引用,确保...

    你必须知道的495个C语言问题.pdf

    - **2.15** 使用`offsetof`宏确定成员的偏移量。 #### 联合 - **2.20** 结构体和联合的主要区别在于内存共享,联合的成员共享同一块内存区域。 #### 枚举 - **2.23** 枚举提供了一种将符号名称与整数关联的方式,...

    Linux内核list&hlist;解读

    可以通过 `offsetof(struct node, value)` 来计算 `value` 成员的偏移量。 ##### 2.3. container_of **2.3.1. 定义** `container_of` 用于从指向结构体成员的指针反向找到指向整个结构体的指针。 ```c #define ...

    actividad-07-sizeof-Alberto-Sotelo:actividad-07-sizeof-Alberto-Sotelo由GitHub Classroom创建

    这也是为什么在某些情况下,你需要使用`offsetof`宏来确定结构体成员相对于结构体开始位置的偏移量。 在"actividad-07-sizeof-Alberto-Sotelo"的项目中,学生可能被要求编写和分析各种示例,例如计算不同类型变量、...

    C++模板类的用法实例

    本文将深入探讨C++模板类的用法,包括其接口、成员以及内联函数的概念和实践。 首先,让我们理解模板类的基本结构。在C++中,模板类的声明通常以关键字`template`开头,后跟一组模板参数。这些参数可以是类型(如`...

    sizeof:Go 数据结构的打印大小

    `Sizeof`函数用于获取一个类型或变量的字节大小,`Alignof`返回类型或变量对齐的字节数,而`Offsetof`则计算结构体字段相对于结构体首地址的偏移量。 2. `Sizeof`的使用:使用`unsafe.Sizeof`时,传入你想要获取...

    《C语言常见问题》(P153)()严立钻监制20140701-08251

    可以通过`offsetof()`宏确定结构体成员的偏移,`sizeof()`计算结构体大小。在运行时访问结构体成员,需要使用`.`或`->`操作符。结构体的序列化和反序列化需要考虑字节顺序和结构体填充。至于“core dump”,通常是...

Global site tag (gtag.js) - Google Analytics