Я смотрел на это intrusive linked list implementation in C, и есть какая-то арифметика указателя, которую я не могу скомпоновать.Указатель Арифметика для Intrusive Связанный список
Во-первых, эта функция и макроэлементов, которые инициируют узел ссылка:
#define LINK_INIT(linkptr, structure, member) \
link_init(linkptr, offsetof(structure, member))
void link_init(link *lnk, size_t offset) {
lnk->next = (void*) ((size_t) lnk + 1 - offset);
lnk->prev = lnk;
}
Я понимаю, что lnk->next (void*) ((size_t) lnk + 1 - offset)
является указателем на следующий структуры в связанном списке, но я не понимаю, почему добавление 1 позволяет указатель на работу по-прежнему, когда смещение - это количество байтов, смещающих член от начала структуры. В struct header definition авторе говорит, что младший бит используется в качестве дозорных для обозначения конца списка, и поэтому lnk->next
указателя может быть & полукольцо с 1 до теста на конце:
// All nodes (=next) must be allocated on (at least) two-byte boundaries
// because the low bit is used as a sentinel to signal end-of-list.
typedef struct link {
struct link *prev;
void *next;
} link;
void* link_next(link *lnk) {
if ((size_t) lnk->next & 1)
return NULL;
return lnk->next;
}
Я Просто интересно, почему это вообще работает? Я смутно понимаю границы распределения, но, по-моему, недостаточно, чтобы понять, почему это работает.
Очень плохой подход! Использование битов в указателе не должно выполняться, если у вас нет очень ограниченного ОЗУ целевого объекта. И тогда связанный список, скорее всего, неправильный подход. И для связанного списка это на самом деле ерунда. Просто используйте _null pointer_. – Olaf
Как вы на самом деле выделили эти указатели? Это '//, потому что младший бит используется как контрольный сигнал, чтобы сигнализировать конец списка. Звучит очень странно. Я не верю, что вы можете (ab) использовать указатель таким образом. –
Использование младшего бита указателя как часового - очень плохая идея, усугубленная приведением к 'size_t'. По крайней мере, бросьте на что-то разумное, например 'intptr_t'. – user3386109