diff --git a/include/nickel/linkedlist.h b/include/nickel/linkedlist.h index d91a018..fcaa565 100644 --- a/include/nickel/linkedlist.h +++ b/include/nickel/linkedlist.h @@ -47,9 +47,13 @@ static inline ni_list_node* ni_list__get_back(ni_list* l) { /* Iter Helpers */ +// helper macro for element traversal, ordering of operations may cause seg faults +// generally just don't remove 'it', this causes it->next on the next loop to segfault #define NI_LIST__FOREACH(lptr) \ for (ni_list_node* it = (lptr)->head.next; it != &(lptr)->head; it = it->next) +// helper macro for element traversal, that also makes a copy of it in tmp +// useful for removing/moving the current node (it) #define NI_LIST_FOREACH_SAFE(tmp, lptr) \ for (ni_list_node* it = (lptr)->head.next, *tmp = it->next; \ it != &(lptr)->head; \ diff --git a/src/nickel/linkedlist.c b/src/nickel/linkedlist.c index bd35c92..8a277ff 100644 --- a/src/nickel/linkedlist.c +++ b/src/nickel/linkedlist.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "nickel/linkedlist.h" @@ -19,6 +20,10 @@ bool ni_list__is_empty(ni_list* l) { } void ni_list__insert_after(ni_list* l, ni_list_node* entry, ni_list_node* n) { + // n must not be in a list already, + // if you need an object in multiple lists, use multiple links. + assert(n->next == NULL && n->prev == NULL); + // setup our incomming node as the next node after the insert point n->next = entry->next; n->prev = entry; @@ -32,6 +37,10 @@ void ni_list__insert_after(ni_list* l, ni_list_node* entry, ni_list_node* n) { } void ni_list__insert_before(ni_list* l, ni_list_node* entry, ni_list_node* n) { + // n must not be in a list already, + // if you need an object in multiple lists, use multiple links. + assert(n->next == NULL && n->prev == NULL); + // setup our incomming node as the next node before the insert point n->prev = entry->prev; n->next = entry; diff --git a/tests/test_linkedlist.c b/tests/test_linkedlist.c index fceb658..46fdedd 100644 --- a/tests/test_linkedlist.c +++ b/tests/test_linkedlist.c @@ -57,6 +57,10 @@ int main (void) t->data3 = rand() % UINT64_MAX; t->data4 = rand() % UINT64_MAX; + // ensure our link points at nothing. + t->link.next = NULL; + t->link.prev = NULL; + ni_list__push_back(&data_instances, &(t->link)); printf("write: n = %d: %ld %ld %ld %ld \n\tnext: %p\n\tprev: %p\n", @@ -75,6 +79,7 @@ int main (void) } } + // drain from back of list and remove then free entries while (!ni_list__is_empty(&data_instances)) { ni_list_node* tail = ni_list__get_back(&data_instances); ni_list__remove(&data_instances, tail);