zoukankan      html  css  js  c++  java
  • offset 和 containof

    1 offset宏定义,offset是用来获取结构体成员的偏移量。

    #define offsetof(type, member) (size_t)&(((type*)0)->member)

    1.1((type*)0) 将内存地址0设置为type指针的起始地址。

    1.2&(((type *)0)->member) 为member的地址,由于(type*)的开始地址为0,那么显然这时menber的地址也就是其偏移量。

    2 container_of,container_of宏用来根据成员的地址来获取结构体的地址。

    #define container_of(ptr, type, member) ({ 
         const typeof( ((type *)0)->member ) *__mptr = (ptr); 
         (type *)( (char *)__mptr - offsetof(type,member) );}) 

    2.1  ptr 变量的地址

          type 要获取的的结构体的名称

          member ptr变量对应的名称

    2.2 const typeof( ((type *)0)->member ) *__mptr = (ptr);

      typeof( ((type *)0)->member )  获取member的类型

      typeof( ((type *)0)->member ) *__mptr = (ptr); 定义一个member类型的指针

    2.3  (type *)( (char *)__mptr - offsetof(type,member) )

         (char *)_mptr 获取_mptr的实际地址,实际上就是ptr

         offsetof(type,meber) 获取member的偏移量

           (type *)( (char *)__mptr - offsetof(type,member) ) ,实际地址_mptr减去偏移量,就是type的起始地址。

    3 offset和container_of测试代码

    #include<stdio.h>
    #include<stdlib.h>
    #include<malloc.h>
    
    //#define offsetof(type, member) (size_t)&(((type*)0)->member)
    #define container_of(ptr, type, member) ({      
        const typeof( ((type *)0)->member ) *__mptr = (ptr);  
        (type *)( (char *)__mptr - offsetof(type,member) );})
    
    typedef struct node{
      int value;
      int key;
    }node_t;
    
    static void test_offset_of()
    {
      int  offset_value = 0;
      int  offset_key = 0;
      
      offset_value = offsetof(node_t,value);
      offset_key = offsetof(node_t,key);
    
      printf("offset_value is %d
    ",offset_value);
      printf("offset_key is %d
    ",offset_key);
    }
    
    static void test_container_of()
    {
      node_t *node1 = (node_t *)malloc(sizeof(node_t));
      node_t *node2 = NULL;
      node_t *node3 = NULL;
    
      if(node1 == NULL)
        return;
    
      int *p_value = &node1->value;
      int *p_key = &node1->key;
    
      node2 = container_of(p_value,node_t,value);
      node3 = container_of(p_key,node_t,key);
    
      printf("node1 addr is %p
    ",node1);
      printf("node2 addr is %p
    ",node2);
      printf("node3 addr is %p
    ",node3);
    
    }
    
    
    int main()
    {
      test_offset_of();
      test_container_of();
    }
    ~                                        
  • 相关阅读:
    Oracle性能优化--DBMS_PROFILER
    Oracle性能优化--AUTOTRACE 操作
    浅谈SQL中的单引号
    pgadmin(IDE)工具连接postgres数据库
    Linux下的PostgreSQL简单安装手册
    es6常用方法总结
    vue下axios和fetch跨域请求
    作用域和作用域链
    ES5函数新增的方法(call、apply、bind)
    js递归和数组去重(简单便捷的用法)
  • 原文地址:https://www.cnblogs.com/bspp1314/p/9294877.html
Copyright © 2011-2022 走看看