Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (GNU/Linux, *NIX, *BSD und Co) » Doppelt verkettete Liste

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
23.05.2009, 12:12 Uhr
~Gordon
Gast


Hallo.

Hallo.

Ich hab einige Probleme bei der Implementierung einer doppelt verketteten Liste, die auf den folgenden Strukturen basieren soll:



Code:
struct list_head {

struct list_head *next, *prev;
};

struct proc_info {

struct list_head head;
int pid;
int counter;
int priority;
};






Die Erste ist zum ansprechen der einzelnen Elemente gedacht und die Zweite zum Daten speichern und nachher ausgeben.

Aber ich begreife irgendwie nicht, wie ich jetzt von einer Struktur auf die andere zugreifen kann.

vielen Dank

Gordon
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
23.05.2009, 13:01 Uhr
0xdeadbeef
Gott
(Operator)


Das ganze sieht mir der sog. "Linux Kernel List" recht ähnlich, eine etwas wilde (aber sehr flexible) C-Konstruktion. Das Konzept ist, dass ein Member vom Typ list_head eine Struktur zu einem Listenknoten macht. Weil der list_head-Member in jeder Instanz der Struktur an der selben Stelle liegt, kann man aus dem Wissen, wo er liegt, die umgebende Struktur rekonstruieren. Das sieht etwa so aus:

C++:
struct list_head {
  struct list_head *prev, *next;
};

struct data_node {
  struct list_head ls;
  int data;
};

/* ... */

struct list_head *ptr;
struct data_node *data_ptr;

/* Nehmen wir an, ptr zeigt auf eine gültige Node */
data_ptr = (struct data_node *)((char *)(ptr) - (ptrdiff_t)(&((struct data_node *)NULL)->ls));


Dabei ist

C++:
(ptrdiff_t)(&((struct data_node *)NULL)->ls)


der Offset des ls-members in einem struct data_node, der vom bekannten Zeiger auf den ls-Member eines struct data_node abgezogen werden muss, um die Adresse des data_node-Structs zu erhalten.

Natürlich wird der ganze Kram am Ende durch Makros verdeckt wie folgt:

C++:
#define list_entry(ptr, type, member) \
    ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))


so dass sich das ganze im Code nachher so liest:

C++:
data_ptr = list_entry(ptr, struct data_node, ls);



Es ist eine etwas dreckige Geschichte, aber in C ist man das ja gewohnt. Komm nur nicht auf die Idee, so was in C++ machen zu wollen!
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (GNU/Linux, *NIX, *BSD und Co) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: