结构体成员变量的偏移值

来源:互联网 发布:淘宝买游戏号可靠吗 编辑:程序博客网 时间:2024/04/25 13:52
1、windows平台下有offsetof宏可以求得结构体成员变量便宜,源码如下:
/* 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)//零地址得出的偏移,相当NULL指针,->符号并没有去执行代码,编译器只是取成员域的地址,避免对象创建,效率大大提高,往往在面试题中出现#endif#endif/* __cplusplus */
2、同样的道理,知道成员变量地址,结构体类型,成员名称,就可以求得:结构体开始地址 = 成员变量地址-offset
windows下有个CONTAINING_RECORD

#define CONTAINING_RECORD(address,type,field) ((type*)((PCHAR)(address)-(ULONG_PTR)(&((type*)0)->field)))

3、Linux的链表和hash表就用到了这种技术

      在linux内核中,链表没有保存数据域,链表节点作为数据节点的域,遍历全局链表或者hash表时,利用上面1、2两点得数据节点的地址。跟一般的链表操作相反。

example 1.1 数据节点结构体

 749struct inode { 750        umode_t                 i_mode; 751        unsigned short          i_opflags; 752        uid_t                   i_uid; 753        gid_t                   i_gid; 754        unsigned int            i_flags; 755 756#ifdef CONFIG_FS_POSIX_ACL 757        struct posix_acl        *i_acl; 758        struct posix_acl        *i_default_acl; 759#endif 760 761        const struct inode_operations   *i_op; 762        struct super_block      *i_sb; 763        struct address_space    *i_mapping; 764 765#ifdef CONFIG_SECURITY 766        void                    *i_security; 767#endif 768 769        /* Stat data, not accessed from path walking */ 770        unsigned long           i_ino; 771        /* 772         * Filesystems may only read i_nlink directly.  They shall use the 773         * following functions for modification: 774         * 775         *    (set|clear|inc|drop)_nlink 776         *    inode_(inc|dec)_link_count 777         */ 778        union { 779                const unsigned int i_nlink; 780                unsigned int __i_nlink; 781        }; 782        dev_t                   i_rdev; 783        struct timespec         i_atime; 784        struct timespec         i_mtime; 785        struct timespec         i_ctime; 786        spinlock_t              i_lock; /* i_blocks, i_bytes, maybe i_size */ 787        unsigned short          i_bytes; 788        blkcnt_t                i_blocks; 789        loff_t                  i_size; 790 791#ifdef __NEED_I_SIZE_ORDERED 792        seqcount_t              i_size_seqcount; 793#endif 794 795        /* Misc */ 796        unsigned long           i_state; 797        struct mutex            i_mutex; 798 799        unsigned long           dirtied_when;   /* jiffies of first dirtying */ 800 801        struct hlist_node       i_hash;  //hash链表 802        struct list_head        i_wb_list;      /* backing dev IO list */ 803        struct list_head        i_lru;          /* inode LRU list */ 804        struct list_head        i_sb_list; 805        union { 806                struct list_head        i_dentry; 807                struct rcu_head         i_rcu; 808        }; 809        atomic_t                i_count; 810        unsigned int            i_blkbits; 811        u64                     i_version; 812        atomic_t                i_dio_count; 813        atomic_t                i_writecount; 814        const struct file_operations    *i_fop; /* former ->i_op->default_file_ops */ 815        struct file_lock        *i_flock; 816        struct address_space    i_data; 817#ifdef CONFIG_QUOTA 818        struct dquot            *i_dquot[MAXQUOTAS]; 819#endif 820        struct list_head        i_devices; 821        union { 822                struct pipe_inode_info  *i_pipe; 823                struct block_device     *i_bdev; 824                struct cdev             *i_cdev; 825        }; 826 827        __u32                   i_generation; 828 829#ifdef CONFIG_FSNOTIFY 830        __u32                   i_fsnotify_mask; /* all events this inode cares about */ 831        struct hlist_head       i_fsnotify_marks; 832#endif 833 834#ifdef CONFIG_IMA 835        atomic_t                i_readcount; /* struct files open RO */ 836#endif 837        void                    *i_private; /* fs or device private pointer */ 838};
example 1.2 链表定义

       struct list_head {223 struct list_head *next, *prev;224 };225226 struct hlist_head {227 struct hlist_node *first;228 };229230 struct hlist_node {231 struct hlist_node *next, **pprev;232 };