简体   繁体   中英

Segfaulting on deletion of a node in a doubly linked list

So what seems to be happening is that my program is not recognizing when a node is set to nullptr...I have no idea why this is. Whenever I check for if(node != nullptr) it seems to pass and go right down into the statement. I may be wrong in saying this, but this is what I think is happening...maybe you may come to a different conclusion. Below is all of the code you should need, please let me know if you need me to post more in order to find the problem.

Thanks for any help ahead of time.

Here's my code

void UseList::deleteNode(std::pair <unsigned, unsigned> data){
node *pre = nullptr, *del = nullptr;

// Check if its the head, if so then delete and update it
if(head->data == data){
    del = head;
    head = del->next;
    delete del;
    return;
}

pre = head;
del = head->next;

while(del != nullptr) { // <----- On the first execution, head is nullptr, so head->next should also be nullptr.  This line should not be allowing the program to descend into the code.
    if(del->data == data){ //   <----- Seg fault occurs here.
        pre->next = del->next;
        if(del = tail)
            tail = pre;
        delete del;
        break;
    }
    pre = del;
    del = del->next;
}
}

Here's a GDB log of where its seg faulting

NOTE: The list is EMPTY when this delete is called. It should be recognizing that head->next is a nullptr and not trying to compare its data with the data to be deleted.

50              while(del != nullptr) {
(gdb)
51                      if(del->data == data){
(gdb)
std::operator==<unsigned int, unsigned int> (__x=..., __y=...)
at c:/mingw/lib/gcc/mingw32/4.8.1/include/c++/bits/stl_pair.h:215
215         { return __x.first == __y.first && __x.second == __y.second; }
(gdb)

Program received signal SIGSEGV, Segmentation fault.
0x00406352 in std::operator==<unsigned int, unsigned int> (__x=..., __y=...)
at c:/mingw/lib/gcc/mingw32/4.8.1/include/c++/bits/stl_pair.h:215
215         { return __x.first == __y.first && __x.second == __y.second; }
(gdb)

Node Class Definition & Constructor

class node {
        public:
            std::pair <unsigned, unsigned> data;
            node *next;
            node *prev;
            node(){
                next = nullptr;
                prev = nullptr;
            }
            ~node(){
                delete next;
            }
    };

List Constructor

UseList::UseList(){
head = tail = nullptr;
head->next = head->prev = nullptr;
tail->next = tail->prev = nullptr;
}

I think it's caused by a typo.

You wrote:

   if(del = tail)
        tail = pre;

You probably meant:

   if(del == tail)
        tail = pre;

Problems that I see

  1. This might not be your problem, but it's worth pointing out. You have:

     if(head->data == data){ 

    This will be a problem if the list is empty, ie head == nullptr .

  2. The code in the constructor is not right. You have:

     UseList::UseList(){ head = tail = nullptr; head->next = head->prev = nullptr; // Since head is nullptr, head->next and head->prev should // produce run time errors. tail->next = tail->prev = nullptr; // Same thing here also. } 
  3. The while loop in deleteNode needs careful walk through to make sure that you are doing the right thing.

    You have:

     if(del->data == data){ pre->next = del->next; if(del = tail) tail = pre; delete del; break; } 

    Let's say you have 25 items in your list and the given data is the 5-th item in the list. At that time, pre points to the 4-th node, del points to the 5-th node. Then you execute:

     pre->next = del->next; // This is good. 

    Then you execute:

      if(del = tail) 

    This statement points del to the tail of the list -- the 25-th node. The expression (del = tail) evaluates to `true. So, you execute:

      tail = pre; 

Now tail points to the 4-th node in the list.

Then you execute:

      delete del;

which deletes the 25-th node of the list.

Now, the list is a strange state. tail points to the 4-th node. The 25-th node has been deleted but the 24-th node still points to it.

If head is nullptr , you cannot access head->next .

So error in this line:

del = head->next; // if head is nullptr

Maybe you could write it differently for the case where head is nullptr .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM