LinuxKernel

カーネル内部で双方向リストを構築するための構造体
2.4.18を読んでいたとき、そのシンプルな構造とアドレス特定テクニックに感心した記憶がある

struct list_head{
   struct list_head *prev;
   struct list_head *next;
}

使い方

struct abc{
   int id;
   struct list_head list;
   char string[80];
}

通常のリストであれば構造体の先頭ポインタでリストを構築するが, list_headでは構造体のメンバlist_headだけでlistを構築する
list_headを定義している<linux/list.h>ではlistへの追加,削除,ループの関数が定義されている.

struct list_head のポインタからメンバを取り出す方法は以下の通り

/**
 * list_entry - get the struct for this entry
 * @ptr:        the &struct list_head pointer.
 * @type:       the type of the struct this is embedded in.
 * @member:     the name of the list_struct within the struct.
 */
#define list_entry(ptr, type, member) \
        ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

具体的にはこのようにして使う

struct block{
  int id;
  struct list_head block_list;
  char string[80];
};

printf("print %d\n",list_entry(listp,struct block,block_list)->id);

構造体先頭からlist_headまでのオフセットを算出し,与えられたlist_headポインタから減じて目的の構造体へのポインタとしている.


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: Sat, 11 Jun 2005 12:31:06 JST (4936d)