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)*****

 

arrow
arrow
    全站熱搜

    hedgezzz 發表在 痞客邦 留言(0) 人氣()