如果我对您的代码有任何了解,
问题1(似是而非):
goList = userInventory;
do {
...
goList = goList->next;
} while (goList != userInventory);
这是一个循环列表吗?如果不是,则条件while ()
不会变为真。
问题2:
goList = userInventory;
do {
if (strcmp(userInventory->username, args[1]) == 0) {
...
}
goList = goList->next;
} while (goList != userInventory);
在这里,您继续比较列表头部(或尾部)中的字符串,而不是比较当前节点中的字符串,goList
. 如果匹配在最初指向的第一个节点(头/尾)中,则仅在上述代码中找到匹配项才能成功userInventory
。
问题3:
temp2 = userInventory->next;
if (userInventory->next != NULL) {
userInventory->next = temp2->next;
userInventory->next->prev = userInventory;
}
free(temp2);
让我们假设userInventory
已经更正为goList
:
temp2 = goList->next;
if (goList->next != NULL) {
goList->next = temp2->next;
goList->next->prev = goList;
}
free(temp2);
首先,它free()
不是匹配节点,而是它之后的节点(或者甚至是NULL
),这是错误的。
其次,这段代码没有对节点进行正确的取消链接和重新链接。它应该是什么(假设列表不是循环的):
temp2 = goList;
if (goList->next != NULL) {
goList->next->prev = goList->prev; // now goList->next node points to goList->prev node
}
if (goList->prev != NULL) {
goList->prev->next = goList->next; // now goList->prev node points to goList->next node
}
free(temp2);
问题4:
do {
if (strcmp(goList->username, args[1]) == 0) {
temp2 = goList;
if (goList->next != NULL) {
goList->next->prev = goList->prev; // now goList->next node points to goList->prev node
}
if (goList->prev != NULL) {
goList->prev->next = goList->next; // now goList->prev node points to goList->next node
}
free(temp2);
}
goList = goList->next;
} while (...);
如果删除成功,此行将访问刚刚释放的节点并可能使您的程序崩溃:
goList = goList->next;
因此,您需要将代码更改为:
do {
if (strcmp(goList->username, args[1]) == 0) {
temp2 = goList;
if (goList->next != NULL) {
goList->next->prev = goList->prev; // now goList->next node points to goList->prev node
}
if (goList->prev != NULL) {
goList->prev->next = goList->next; // now goList->prev node points to goList->next node
}
goList = goList->next;
free(temp2);
}
else
{
goList = goList->next;
}
} while (...);
问题 5:
goList = userInventory;
如果删除列表头(或者是尾?)节点,则需要更新userInventory
以指向它之后的下一个节点。如果不这样做,您将失去对列表的所有访问权限,因为userInventory
将指向已释放的内存,而不是指向剩余节点(如果有)。
问题 6(似是而非):
free(temp2);
上面的行没有free()
后面的记忆temp2->username
。free()
如果它是malloc()
ed ,你想要它。
您真的应该一次一步解决问题(例如,首先,遍历列表,然后取消链接/重新链接节点,然后删除节点)。
当事情不清楚或不起作用时,请使用纸和铅笔(或绘图板和钢笔或粉笔)自己想象问题。绘制对象,箭头描绘指针或它们之间的一些其他连接等,在对象旁边涂抹变量名称,以便您可以清楚地看到如何从图表进展到代码。