Как использовать список из sys / queue.h?

в настоящее время я реализовал один связанный список, например:

struct PeerNode {
     struct Peer* cargo;
     struct PeerNode* next;
};

...и у меня есть структура, которая содержит пару этих связанных списков, например:

struct Torrent {
     ...
     struct PeerNode* peer_list;
     struct PeerNode* unchoked_peers;
     ...
}

Я хотел бы заменить это, используя макросы, предоставленные sys/queue.h. Я понял, что могу заменить свой код чем-то вроде этого:

struct Torrent {
     ...
     LIST_ENTRY(PeerNode, Peer) peer_list;
     struct PeerNode* unchoked_peers;
     ...
}

тогда, глядя на man queue, Я считаю, что я бы инициализировал списки, делая что-то вроде это:

LIST_INIT(&peer_list);
LIST_INIT(unchoked_peers);

однако, я не понимаю, как LIST_ENTRY факторы в использовании список. От man страница, она говорит: "макрос LIST_ENTRY объявляет структуру, которая соединяет элементы в списке, " но я действительно не понимаю, что это значит.

зачем мне объявлять структуру для подключения элементов в списке? Разве каждый узел не должен быть подключен к следующему узлу с помощью указателя, как моя первоначальная реализация связанного списка? Как бы Я заменил свою связанные списки с реализацией предусмотренных sys/queue.h? Как вставить элемент в список?

1 ответов


LIST_ENTRY создает поля для размещения в вашей структуре, которые подходят для связывания элементов, поэтому вам не нужно беспокоиться о специфике этих указателей.

struct foo {
    int a, b, c;
    /* This is instead of "struct foo *next" */
    LIST_ENTRY(foo) pointers;
};

чтобы создать список, вы должны использовать LIST_HEAD ():

struct Torrent {
    LIST_HEAD(foo_list, foo) bar;
};

вы можете инициализировать заголовок списка с помощью LIST_INIT ():

struct Torrent t;
LIST_INIT(&t.bar);

вы можете вставлять элементы с помощью макросов LIST_INSERT_* ():

struct foo *item = malloc(sizeof(struct foo));
LIST_INSERT_HEAD(&t.bar, item, pointers);

Это все было взято из примера списка в man pages at http://www.manpagez.com/man/3/queue/

полный пример: http://www.ideone.com/T1EID