offsetof 傳回一個變數在一個結構的 offset , 這個在你需要轉換指標時有用,
我在 intrusive linked list 也用到這個 function :
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
struct foo {
struct foo *next;
int a;
int b;
int c;
int x[3] ;
};
void iterate(struct foo *list, size_t off)
{
struct foo *p = list;
int i = *(int *)((char *)p + off); /* [1] */
printf("(%d)\n",i) ;
}
void func(struct foo *f)
{
iterate(f, offsetof(struct foo, a));
iterate(f, offsetof(struct foo, b));
iterate(f, offsetof(struct foo, c));
iterate(f, offsetof(struct foo, x[0]));
iterate(f, offsetof(struct foo, x[1]));
iterate(f, offsetof(struct foo, x[2]));
}
typedef struct Mars
{
int id ;
int* iptr[5] ;
} Mars;
int main ()
{
struct foo *f = (struct foo*) malloc(sizeof(struct foo)) ;
f->a = 100 ;
f->b = 200 ;
f->c = 300 ;
f->x[0] = 400 ;
f->x[1] = 500 ;
f->x[2] = 600 ;
func(f) ;
Mars* mars = (Mars*) malloc(sizeof(Mars)) ;
mars->id = 12345 ;
int idx ;
for(idx=0;idx<5;idx++)
{
mars->iptr[idx] = (int*) malloc(sizeof(int*)) ;
*(mars->iptr[idx]) = idx * idx ;
}
size_t off0 = offsetof(Mars,id) ;
printf("off0=(%d)\n",off0) ;
int i = *(int *)((char *)mars + off0);
printf("id=(%d)\n",i ) ;
size_t off2 = offsetof(Mars,iptr[0]) ;
printf("off2=(%d)\n",off2) ;
for(idx=0;idx<5;idx++)
{
size_t offx = off2 + sizeof(int*) * idx ;
int* i1 = *(int **)((char *)mars + offx);
printf("(%d)\n",*i1) ;
}
int* px[5] ;
for(idx=0;idx<5;idx++)
{
px[idx] = (int*) malloc(sizeof(int*)) ;
*(px[idx])=idx ;
}
for(idx=0;idx<5;idx++)
{
printf("*****(%d)*****\n",*(px[idx]) );
printf("*****(%d)*****\n",*(*(px+idx)) );
}
return 0;
}
Result :
(100)
(200)
(300)
(400)
(500)
(600)
off0=(0)
id=(12345)
off2=(4)
(0)
(1)
(4)
(9)
(16)
*****(0)*****
*****(0)*****
*****(1)*****
*****(1)*****
*****(2)*****
*****(2)*****
*****(3)*****
*****(3)*****
*****(4)*****
*****(4)*****
留言列表