【问题标题】:c++: double free or corruption (fasttop)c++:双重释放或损坏(fasttop)
【发布时间】:2016-08-19 16:19:10
【问题描述】:

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

}

谢谢。

【问题讨论】:

  • 如果你试图在你的列表中找到一个循环,那么为什么在第一个循环中你会踩到你的列表?
  • 听起来您可能需要学习如何使用调试器来逐句执行代码。使用好的调试器,您可以逐行执行程序并查看变量的值并监控它与您期望的偏差。如果您要进行任何编程,这是必不可少的工具。
  • 看来你的循环逻辑坏了。例如,当 A->next == A 时会发生什么? temp1->next = A->next 也很奇怪。如果循环中断了 1000 个节点怎么办,为什么会涉及 A->next?
  • 别猜了。使用调试器,单步调试代码并找出答案。这是编程的一部分,是必须学习的技能。
  • “我的代码编译”并不神奇地意味着它没有问题。它只是没有任何编译器可以发现

标签: c++ pointers memory-leaks


【解决方案1】:

作为直接答案,您的代码正在崩溃,因为您正在访问已经空闲的节点。除了访问之外,您正在删除一个已经被删除的节点。这种“双重免费”几乎总是会导致崩溃或其他混乱。深入了解 C/C++ 中的堆机制会为你省去很多痛苦,值得学习。

我不太确定要求是什么,但我相信您正在尝试检查循环链表。我不清楚您为什么要删除“检测”方法中的任何节点。你想打破循环吗?如果是这样,所有节点仍将在列表中,因此不会删除任何内容,只需将循环返回的节点上的 ->next 更改为 nullptr 即可。

以下是您的原始代码中的一些示例代码。我使用您的代码作为基础创建它,然后使用 gdb 调试器对其进行调试。一个有效的软件工程师是调试器的大师,拥抱它。它是 cmets 中描述的最小、完整和可验证的示例。

我将一些测试作为“用例”的示例,没有循环、退化循环、更长的循环。作为软件工程师,我们工作的很大一部分是考虑经常发生在边界上的错误案例。可能还有其他我没有涵盖的内容。

如 cmets 中所述,编译或单个成功用例并不表示软件没有缺陷。需要进行严格的测试才能获得信心。这种测试通常被称为“单元测试”,有大量关于该主题的文献。

#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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 2017-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多