我正在尝试通过链表找到一种将void指针存储到内存块的方法,并且我遇到了这种表示。
//Initalization
void * list;
//Add void pointer
void add_pointer(void * p) {
*(void **)p = list;
list = p;
}
//Remove pointer with address
void remove_pointer(void * p) {
void ** iter;
iter = &list;
while ((*iter != NULL) && (*iter != p)) {
iter = (void **)*iter;
}
if (*iter == p) {
*iter = *(void **)p;
}
}
这怎么工作?下一个块的地址是否存储在void指针所指向的前一个块的数据中?假设列表初始化为NULL。
另外,这是否假设每个void指针的块都没有写入数据?如果任何人都可以了解这个实现是如何工作的,那将是非常好的,它似乎非常深奥,它可以作为一个链表。
答案 0 :(得分:2)
它只是假设节点的第一个字段是链接指针的插槽。它将节点指针强制转换为(void**)
,以便它可以在该地址存储void*
。
当然,list
是指向链表上第一个节点的指针的硬编码位置。
不是最灵活的列表设计。
答案 1 :(得分:2)
它假定节点中的第一个字段是链接指针的槽,即void *
。 list
是void *
,它始终指向链接列表的头部。
add_pointer()
函数将新节点添加到列表的开头。 void *p
参数指向要添加的新节点。该函数将void *
p转换为void **
,以便*(void **)p
可以保存void *
指针。该函数将前一个头指针存储在此位置
*(void **)p = list; // list is a void * to the first element
然后将list
设置为新的第一个元素的void *
,即p。
现在remove_pointer()
函数从列表中删除一个节点,将void *
作为参数指向它。 iter
用于迭代列表。它最初被分配了list
的地址,以便*iter
将给出链接指针,该指针被假定为节点中的第一个字段。 while循环将iter
更新到列表中的下一个节点,直到它在当前节点的链接指针字段中找到p
(要删除的节点)。此时,它更新当前节点的链接指针字段以指向由p指向的节点的链接指针字段值,这由语句
*iter = *(void **)p; // *iter gives the link pointer filed of the current node
// p, is the node to be removed, *(void **)p gives the value in
// the link pointer filed of p