日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux / offsetof 和 container_of

發布時間:2024/10/14 linux 67 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux / offsetof 和 container_of 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
@time 2019-07-10 @author Ruo_Xiao @revision linux 2.6.11

1、?offsetof?

(1)原型

/** @member TYPE : 結構體原型。* MEMBER : 結構體成員。 */ #define offsetof(TYPE , MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

?

(2)文件路徑:/ include / linux / stddef.h

(3)作用

返回指定類型(TYPE)的成員(MEMBER)在該結構體內的偏移量。

(4)解析

? ? ? ? ?A、(TYPE *) 0

? ? ? ? ? ? ? ? ? 將以地址 0 為開始的,大小為 sizeof(TYPE) 的內存塊按照 TYPE 進行看待。注意,這里只是看待,并沒有進行讀? ? ? ? ? ? ? ? 取!這就保證了代碼執行到這里并不會報錯!

? ? ? ? ?B、((TYPE *) 0) -> MEMBER

? ? ? ? ? ? ? ? ? 看看 MEMBER 成員,還是沒有讀取。

? ? ? ? ?C、&(((TYPE *) 0) -> MEMBER)

? ? ? ? ? ? ? ? ?看看 MEMBER 成員地址,還是沒有讀取。因為結構體的首地址為0,所以得到的 MEMBER 的首地址就是該成員相對? ? ? ? ? ? 于結構體首地址的偏移量。

? ? ? ? ?D、(size_t)&(((TYPE *)0) -> MEMBER)

? ? ? ? ? ? ? ? ?將該地址轉為 size_t 類型。

? ? ? ? ? 在32位系統中,size_t 的原型是 unsigned int

? ? ? ? ? 在64位系統中,size_t 的原型是 unsigned long

(5)栗子

#include <iostream>#define offsetof_t(TYPE , MEMBER) ((size_t)&(((TYPE *)0)->MEMBER))struct stest {char c;int i;float f;double d; };int main() {int pos_c = offsetof_t(stest , c);int pos_i = offsetof_t(stest , i);int pos_f = offsetof_t(stest , f);int pos_d = offsetof_t(stest , d);std::cout << "stest::c 的偏移量:" << pos_c << std::endl;std::cout << "stest::i 的偏移量:" << pos_i << std::endl;std::cout << "stest::f 的偏移量:" << pos_f << std::endl;std::cout << "stest::d 的偏移量:" << pos_d << std::endl;return 0; }

結果:

stest::c 的偏移量:0 stest::i 的偏移量:4 stest::f 的偏移量:8 stest::d 的偏移量:16

?

2、container_of

(1)原型

/** @member ptr 結構體成員的地址。* type 結構體原型。* member 結構體成員。*/ #define container_of(ptr, type, member) ({ \const typeof( ((type *)0)->member ) *__mptr = (ptr); \(type *)( (char *)__mptr - offsetof(type,member) );})

(2)文件路徑:/ include / linux / kernel.h

(3)作用:通過結構體成員地址反推該結構體的地址。

(4)解析

? ? ? ? ?A、typeof(? ( (type*)0 ) -> member ) )

? ? ? ? ? ? ? ? ? 獲得 member 成員的數據類型。

? ? ? ? ?B、const?typeof(? ( (type*)0 ) -> member ) )? *_mptr = (ptr)

? ? ? ? ? ? ? ? ? 定義常量指針?_mptr,指向 ptr 指向的內容,該指針變量指向的內容是不可變的。

? ? ? ? ?C、(char *)_mptr - offsetof(type , member)

? ? ? ? ? ? ? ? ? 前者將 _mptr 變為 字符指針,后者返回 member 在 type 的偏移量,二者相減就是 type 的首地址了。

? ? ? ? ? ?最后在通過? (type *) 轉為 type 型地址就可以了。

(5)栗子

#include <iostream>struct stest {char c;int i;float f;double d; };#define offsetof_t(TYPE , MEMBER) ((size_t)&(((TYPE *)0)->MEMBER))#define container_of_test(ptr , type , member) ({\const typeof(((type *)0)->member) *_mptr = ptr;\(type *)((char *)ptr - offsetof_t(type , member));})int main() {stest test1;stest *p;p = container_of_test(&test1.i , stest , i);if (p == &test1){std::cout << "二者相同。" << std::endl;}else{std::cout << "二者不同。" << std::endl;} }

結果:

二者相同

?

?

(SAW:Game Over!)

總結

以上是生活随笔為你收集整理的Linux / offsetof 和 container_of的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。