重新排列双向链表时偶尔会出现段错误
Occasional Segfault when rearranging doubly linked list
如果这对某些人来说似乎微不足道,我很抱歉,但在过去的一天里,我终究无法弄清楚为什么会出现此段错误。我有一个双向链表数组,我在其中维护特定顺序。每次访问或更新列表中的节点时,它都会移动到列表的头部,并且这发生在数组中的每个链表中。我将提供有关如何初始化链表数组以及如何排列顺序的代码。任何帮助表示赞赏。如果有帮助,双向链表的数组是为了模拟缓存。我只是希望它的东西非常明显,因为我对 malloc 和 C 有点陌生。第一次使用这个网站所以请让我知道我是否没有遵循惯例或我的 post
做错了什么
我试过打印链表数组的结构,它似乎总是结构合理。段错误仅在我重新排列节点时发生,特别是当我尝试访问 Node->prev->next 时。不仅如此,当我专门更新尾节点时也会发生这种情况
void maintainLRU(cacheBlock* ptr, int index)//rearranges a list with node passed in to be head
{
if(ptr->next == NULL)//Tail
{
ptr->next = cache[index].head;
cache[index].head = ptr;
cache[index].tail = ptr->prev;
ptr->prev->next = NULL;
ptr->prev = NULL;
}
else
{
ptr->prev->next = ptr->next;
ptr->next = cache[index].head;
cache[index].head = ptr;
ptr->prev->next = NULL;
ptr->prev = NULL;
}
}
//following code exists within main and is how i initialize the'cache'
numLines = cacheSize/(blockSize*assocType); //determines number of linked lists in my array.
cache = malloc(sizeof(cacheLine)*numLines);
for(int i = 0; i < numLines; i++)
{
cacheBlock* temp = malloc(sizeof(cacheBlock));
temp->valid = 0; //whether the node holds data yet or not
cache[i].head = temp;
for(int j = 1; j < assocType; j++)//assoctype is just how many nodes in the list
{
temp->next = malloc(sizeof(cacheBlock));
temp->next->prev = temp;
temp->next->valid = 0;
temp = temp->next;
}
cache[i].tail = temp;
}//cacheblock is just a node with next, prev, and a valid bit
//cacheLine is just a struct with a pointer to a headnode
//the maintain order function is explicitly called only if the node updated or accessed is not the head.```
情况 1:ptr 在列表末尾
你适当地删除自己,将自己放在列表的头部,但不要让列表的“旧”头部指向你;所以您的列表已损坏。
情况 2:ptr 不在列表末尾
你将 prev 指向你的下一个,但不要将你的 next 指向你的 prev,这样你的列表就会损坏。
所有情况:您应该提供足够的程序,以便有人可以编译并试用。在某种程度上,这会让你充分分析你的工作,以注意到明显的错误。微妙的是这个论坛的目的。
3 年前,严格优化链表操作非常重要;在那段时间编译器的书呆子已经提高了他们的游戏水平,你应该能够将 maintainLRU 写成:
void maintainLRU(cacheBlock* ptr, int index) {
list_remove(&cache[index], ptr);
list_insert_before(&cache[index], cache[index].head, ptr);
}
所以你不会成为简单错误的牺牲品。
如果这对某些人来说似乎微不足道,我很抱歉,但在过去的一天里,我终究无法弄清楚为什么会出现此段错误。我有一个双向链表数组,我在其中维护特定顺序。每次访问或更新列表中的节点时,它都会移动到列表的头部,并且这发生在数组中的每个链表中。我将提供有关如何初始化链表数组以及如何排列顺序的代码。任何帮助表示赞赏。如果有帮助,双向链表的数组是为了模拟缓存。我只是希望它的东西非常明显,因为我对 malloc 和 C 有点陌生。第一次使用这个网站所以请让我知道我是否没有遵循惯例或我的 post
做错了什么我试过打印链表数组的结构,它似乎总是结构合理。段错误仅在我重新排列节点时发生,特别是当我尝试访问 Node->prev->next 时。不仅如此,当我专门更新尾节点时也会发生这种情况
void maintainLRU(cacheBlock* ptr, int index)//rearranges a list with node passed in to be head
{
if(ptr->next == NULL)//Tail
{
ptr->next = cache[index].head;
cache[index].head = ptr;
cache[index].tail = ptr->prev;
ptr->prev->next = NULL;
ptr->prev = NULL;
}
else
{
ptr->prev->next = ptr->next;
ptr->next = cache[index].head;
cache[index].head = ptr;
ptr->prev->next = NULL;
ptr->prev = NULL;
}
}
//following code exists within main and is how i initialize the'cache'
numLines = cacheSize/(blockSize*assocType); //determines number of linked lists in my array.
cache = malloc(sizeof(cacheLine)*numLines);
for(int i = 0; i < numLines; i++)
{
cacheBlock* temp = malloc(sizeof(cacheBlock));
temp->valid = 0; //whether the node holds data yet or not
cache[i].head = temp;
for(int j = 1; j < assocType; j++)//assoctype is just how many nodes in the list
{
temp->next = malloc(sizeof(cacheBlock));
temp->next->prev = temp;
temp->next->valid = 0;
temp = temp->next;
}
cache[i].tail = temp;
}//cacheblock is just a node with next, prev, and a valid bit
//cacheLine is just a struct with a pointer to a headnode
//the maintain order function is explicitly called only if the node updated or accessed is not the head.```
情况 1:ptr 在列表末尾 你适当地删除自己,将自己放在列表的头部,但不要让列表的“旧”头部指向你;所以您的列表已损坏。
情况 2:ptr 不在列表末尾 你将 prev 指向你的下一个,但不要将你的 next 指向你的 prev,这样你的列表就会损坏。
所有情况:您应该提供足够的程序,以便有人可以编译并试用。在某种程度上,这会让你充分分析你的工作,以注意到明显的错误。微妙的是这个论坛的目的。
3 年前,严格优化链表操作非常重要;在那段时间编译器的书呆子已经提高了他们的游戏水平,你应该能够将 maintainLRU 写成:
void maintainLRU(cacheBlock* ptr, int index) {
list_remove(&cache[index], ptr);
list_insert_before(&cache[index], cache[index].head, ptr);
}
所以你不会成为简单错误的牺牲品。