c ++:双重免费或腐败(fasttop)

时间:2016-08-19 16:19:10

标签: c++ pointers memory-leaks

我正在尝试在列表中找到循环开始的节点。 返回的结果是正确的。但是,在./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;
    }

}

谢谢。

1 个答案:

答案 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;
}