我正在尝试在列表中找到循环开始的节点。 返回的结果是正确的。但是,在./solution中出现 *错误的错误:双重免费或损坏(fasttop):0x0000000000b3e030
显示已中止。我看到了一些其他类似的问题,我认为问题出在temp1=temp;
。但我不知道如何解决这个问题。
怎么纠正呢?另外,为什么会出现这种错误?
ListNode* Solution::detectCycle(ListNode* A) {
ListNode* temp = A;
ListNode* temp1 = A;
while(temp->next!=NULL && temp->next->next!=A->next ){
temp1 = temp;
temp = temp->next;
temp1->next=A->next;
}
if(temp->next==NULL) {
temp->val=-1;
delete temp1;
return temp;
}
else {
temp= temp->next;
delete temp1;
return temp;
}
}
谢谢。
答案 0 :(得分:1)
直接回答,您的代码崩溃了,因为您正在访问已经空闲的节点。除了访问之外,您正在删除已被删除的节点。这种“双重免费”几乎会导致崩溃或其他混乱。对C / C ++中堆函数的深刻理解将为您节省很多痛苦,值得研究。
我不太确定要求是什么,但我相信您正在尝试检查循环链表。我不清楚为什么要删除'detect'方法中的任何节点。你想破坏循环吗?如果是这样,所有节点仍将在列表中,因此不会删除任何内容,只需更改循环返回的节点上的nullptr旁边的 - >即可。
以下是原始代码中的一些示例代码。我使用您的代码作为基础创建它,然后使用gdb调试器进行调试。一个有效的软件工程师是调试器的主人,拥抱它。它是评论中描述的最小,完整和可验证的示例。
我把一些测试作为'用例'的例子,没有循环,退化循环,更长的循环。作为软件工程师,我们工作的很大一部分是考虑经常出现在边界上的错误情况。可能还有其他我没有涉及的内容。
如评论中所述,编译或单个成功用例并不表示无缺陷软件。需要严格的测试才能获得信心。这种测试通常被称为“单元测试”,有大量关于该主题的文献。
#include <iostream>
struct ListNode
{
int val;
ListNode* next;
};
//Look for a loop back to A
ListNode* detectCycle(ListNode* A) {
if(A == nullptr) // can't be a loop if list is empty
return nullptr;
ListNode* temp = A;
while(temp->next!=NULL && temp->next !=A ){
temp = temp->next;
}
if(temp->next==NULL) {
return nullptr; // No loop
}
else {
return temp; // Node where loop starts, may be A itself
}
}
int main(int argc,char* arv[])
{
ListNode *a = new ListNode;
ListNode *loop = nullptr;
loop = detectCycle(a);
if(loop == nullptr)
std::cout << "Case 1 passed" << std::endl;
a->next = a;
loop = detectCycle(a);
if(loop == a)
std::cout << "Case 2 passed" << std::endl;
ListNode *b = new ListNode;
ListNode *c = new ListNode;
ListNode *d = new ListNode;
a->next = b;
b->next = c;
c->next = d;
d->next = a;
loop = detectCycle(a);
if(loop == d)
std::cout << "Case 3 passed" << std::endl;
loop = detectCycle(b);
if(loop == a)
std::cout << "Case 4 passed" << std::endl;
return 0;
}