2012-04-21 3 views
6

J'essaie de comprendre l'API de la liste chaînée du noyau Linux.Différence entre LIST_HEAD_INIT et INIT_LIST_HEAD

Selon Linux Kernel Linked List j'initialiser la tête de liste par INIT_LIST_HEAD mais here (Linux Kernel Program) il est suggéré d'utiliser LIST_HEAD_INIT à la place.

Voici un code de travail que j'ai écrit, mais je ne suis pas sûr de l'avoir fait correctement. Quelqu'un pourrait-il vérifier que tout va bien?

#include <stdio.h> 
#include <stdlib.h> 
#include "list.h" 

typedef struct edge_attr { 
     int d; 
     struct list_head list; 
} edge_attributes_t; 

typedef struct edge { 
     int id; 
     edge_attributes_t *attributes; 
} edge_t; 

int main() { 
     int i; 
     struct list_head *pos; 
     edge_attributes_t *elem; 
     edge_t *a = (edge_t*)malloc(sizeof(edge_t)); 

     a->id = 12; 
     a->attributes = (edge_attributes_t*) malloc(sizeof(edge_attributes_t)); 

     INIT_LIST_HEAD(&a->attributes->list); 

     for (i=0; i<5; ++i) { 
       elem = (edge_attributes_t*)malloc(sizeof(edge_attributes_t)); 
       elem->d = i; 
       list_add(&elem->list, &a->attributes->list); 
     } 

     list_for_each(pos, &(a->attributes->list)) { 
       elem = list_entry(pos, edge_attributes_t, list); 
       printf("%d \n", elem->d); 
     } 

     return 0; 
} 
+0

ou maby a-> atrributes devrait être juste une tête de liste, pas une entrée de liste? – patseb

Répondre

10

Une recherche LXR rapide montre:

#define LIST_HEAD_INIT(name) { &(name), &(name) } 

static inline void INIT_LIST_HEAD(struct list_head *list) 
{ 
     list->next = list; 
     list->prev = list; 
} 

Alors INIT_LIST_HEAD obtient un struct list head * et initialise, tandis que LIST_HEAD_INIT retourne l'adresse du pointeur passé dans un fashioned approprié pour être utilisé comme un initialiseur pour une liste :

struct list_head lst1; 
/* .... */ 
INIT_LIST_HEAD(&lst1); 



struct list_head lst2 = LIST_HEAD_INIT(lst2); 
+0

struct list_head lst1; INIT_LIST_HEAD (&lst1); renvoie l'erreur: 'struct list_head' n'a aucun membre nommé 'list' – patseb

17

LIST_HEAD_INIT est un initialiseur statique, est un INIT_LIST_HEAD fonction. Ils initialisent tous deux un list_head pour être vide.

Si vous déclarez statiquement un list_head, vous devez utiliser LIST_HEAD_INIT, par exemple:

static struct list_head mylist = LIST_HEAD_INIT(mylist); 

Vous devez utiliser INIT_LIST_HEAD() pour une tête de liste qui est allouée dynamiquement, généralement partie d'une autre structure. Il y a beaucoup d'exemples dans la source du noyau.