-3

I am trying to find the node where the cycle begins in the list. The result returned is correct. However, an error stating * Error in ./solution: double free or corruption (fasttop): 0x0000000000b3e030 Aborted is shown. I saw some other similar problems, and I think the problem is with temp1=temp;. But I don't know how to solve this problem. How to correct it? Also why is this error occurring?

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

}

Thank you.

Gopal Mishra
  • 1
  • 1
  • 1
  • 4
  • Do you know what line in your program causes the error? – NathanOliver Aug 19 '16 at 16:20
  • 1
    If you're attempting to find a loop in your list,, then why in the first loop are you stomping all over your list? – Tom Tanner Aug 19 '16 at 16:23
  • 6
    It sounds like you may need to learn how to use a debugger to step through your code statement by statement. With a good debugger, you can execute your program line by line and see values of your variables and monitor where it is deviating from what you expect. This is an essential tool if you are going to do any programming. – Khalil Khalaf Aug 19 '16 at 16:25
  • 2
    It seems your loop logic is broken. For example what happens when A->next == A? The temp1->next = A->next is also odd. What if the loop is 1000 nodes down, why would A->next be involved? – Matthew Fisher Aug 19 '16 at 16:25
  • 1
    The right tool to solve such problems is to use your debugger, but not to ask at Stack Overflow before you did so. Tell us all your observations you made when inspecting your code stepping through line by line in 1st place. Also you might want to read [**How to debug small programs (by Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)**] At least leave us with a **[MCVE]** that reproduces your problem. (This is a personal stock comment provided by πάντα ῥεῖ™) – πάντα ῥεῖ Aug 19 '16 at 16:27
  • As I have already stated that the value returned is not wrong. My code returns the correct value. The code compiles well. I am trying to solve [this question](https://www.interviewbit.com/problems/list-cycle/) . – Gopal Mishra Aug 19 '16 at 16:30
  • 1
    @GopalMishra They are not talking about compiling. Debugging is where you step through running code to see what is going on. Doing that will allow you to find out where the error comes from and why if you know what to look for. This is something you have to do to help us help you. – NathanOliver Aug 19 '16 at 16:32
  • @NathanOliver As my code compiles well, I do not know which line is causing the error. but from this [accepted answer] (http://stackoverflow.com/questions/20019512/double-free-or-corruption-fasttop) I guess the 7th line `temp1 = temp;` is causing it. Plz help – Gopal Mishra Aug 19 '16 at 16:33
  • 2
    Don't guess. Use the debugger, step through your code and find out. This is part of programming and is a must learn skill. – NathanOliver Aug 19 '16 at 16:34
  • 2
    "my code compiles" doesn't magically mean it hasn't got problems. It just hasn't got any the compiler can spot – Tom Tanner Aug 19 '16 at 16:35
  • Why does a function that detects a cycle also modify the list? – molbdnilo Aug 19 '16 at 17:16
  • And pen(cil) and paper is still the best tool for debugging pointer-based data structures. – molbdnilo Aug 19 '16 at 17:24
  • 1
    Possible duplicate of [How to track down a "double free or corruption" error](https://stackoverflow.com/questions/2902064/how-to-track-down-a-double-free-or-corruption-error) – Raedwald Dec 06 '18 at 13:38

1 Answers1

1

As a direct answer, your code is crashing because your are accessing nodes that are already free. Beyond accessing, you are deleting a node that has already been deleted. This 'double free' will almost alway result in a crash or other chaos. A strong understanding of heap mechanics in C/C++ will save you a lot of misery, it is worth studying.

I'm not too sure what the requirements are but I believe your are trying to check for a circular linked list. I not clear why you are deleting any of the nodes in a 'detect' method. Are you trying to break the loop? If so, all of the node will still be in the list so nothing will be deleted, just change the ->next to nullptr on the node that loops back.

Here is some example code from your original. I created it using your code as a base and then using the gdb debugger to debug it. An effective software engineer is a master of the debugger, embrace it. It is a Minimal, Complete and Verifiable example as described in the comments.

I put a few tests as an example of 'use cases', no loop, degenerate loop, longer loop. As software engineers, a big part of our job is thinking about error cases which often occur on the boundaries. There may be others that I have not covered.

As noted in the comments, compiling or a single successful use case doesn't indicate defect free software. Rigorous testing is needed to gain confidence. This kind of testing is often referred to as 'unit testing' there is a large body of literature on the subject.

#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;
}
Matthew Fisher
  • 2,258
  • 2
  • 14
  • 23