#define list_entry(ptr, type, member) \ ((type *)(() -> member))) 解释: 1 在0这个地址看做有一个虚拟的type类型的变量,那么取一个成员再取这个成员的地址,就是这个结构体中这个成员的绝对地址 . 2 这句话的意思是获取一个结构体中一个成员在这个结构体中的偏移.type *0是为了计算地址方便.意思是在0这个地址看做有一个虚拟的type类型的变量,那么取一个成员再取这个成员的地址,就是这个结构体中这个成员的绝对地址,由于结构体在…
倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of 这两个宏应该不陌生.这两个宏最初是极客写出的,后来在Linux内核中被推广使用. 1. offsetof 1.1 offsetof介绍 定义:offsetof在linux内核的include/linux/stddef.h中定义.#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 说明:获得结构体(TYPE)的变量成员(…
#define list_entry(ptr, type, member) container_of(ptr, type, member) 在进行编程的时候,我们经常在知道结构体地址的情况下,寻找其中某个成员的地址:但是知道了成员的地址,如果找到这个结构体对应的地址呢? Linux内核中,获取节点地址的函数是list_entry(),它的宏定义如上所示. 我们再来查找container_of(ptr, type, member)的定义,发现它依然是一个宏定义: #define container…
1. struct //是C中的结构体的关键词.如: stuct node{ int a;.....} a; node 相当于结构体的类型,关键是其实在C中stuct node 才相当于一个数据类型,如int ,所以在才会给初学者的带来困难,如在定一个变量时,要用 struct node xxx,而不是 node xxx 这就是关键.a是struct node类型结构体的变量 注意:在c++中定义结构体类型变量可以不用使用struct,例如可以node xxx 2. 而 typedef // 是…
linux内核提供了一个container_of()宏,可以根据结构体某个成员的地址找到父结构的地址. #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr);\ (type *)( (char *)__mptr - offsetof(type,member) );) 而在Nginx也是效仿采用一样的宏获取父结构地址. #define ngx_queue_da…
[DllImport("Iphlpapi.dll")] private static extern int SendARP(Int32 dest, Int32 host, ref Int64 mac, ref Int32 length); [DllImport("Ws2_32.dll")] private static extern Int32 inet_addr(string ip); /// <summary> /// 获取客户机MAC地址 根据IP…
1. 问题描述: 现在定义了一个结构体: struct Foo { int a; int b; }; Foo foo; 假如由于函数传参等原因,现在程序只能拿到 foo.b 的地址,这时想通过某种方法获取到 foo 结构体里的其他成员. 那么问题来了,这就是以下主要讨论的内容. 2. 原理概述 将地址 0 强制转换成一个结构体指针,伪代码:  struct foo *p = (struct Foo *)0; 从而通过已知的结构体成员的地址减去结构体的首地址得到已知结构体成员的内存偏移 , 伪代码…
struct的成员对齐 注意:为了方便说明,等号左边是每个数据单独所占长度,右边是最终空间大小,以字节为单位. 一.什么时间存在对其问题:(32位机对齐方式是按照4字节对其的,以下所有试验都是在32位机上验证的) 当结构体成员数据按照其顺序组合,无法按4字节对齐时,存在对其问题. 如: 1+1=2: 1+2=3: 1+2+1=4(而不是6或者其他): 2+1=3:(不是4) 以上是不存在对其问题的(因为没有超过4字节). 如: 1+4=8: 4+1=8: 1+4+1=12: 1+2+4=8: 1…
看nginx代码时发现双链表使用的是这种方法,记录一下 给出一个实例来说明 struct father_t {    int a;    char *b;    double c;}f;char *ptr = &(f.b);//而不是 ptr = f.b; 这里ptr是b的地址,而不是它指向的地址. 根据C语言对struct类型的存储特性,我们可以画这么一个图示:通过分析图示,我们可以看出,我们只需要把当前知道的成员变量的地址ptr,减去它在结构体当中相对偏移4就的到了结构体的地址(ptr-4)…
package main import ( "fmt" "unsafe" ) func main() { // 根据内存地址获取下一个字节内存地址对应的值 dataList := [3]int8{11, 22, 33} // 1. 获取数组第一个元素的地址 var firstDataPtr *int8 = &dataList[0] // 2. 转换成Pointer类型 ptr := unsafe.Pointer(firstDataPtr) // 3. 转换成…