c++ - 删除双向链表中的节点时发生段错误

标签 c++ linked-list segmentation-fault doubly-linked-list

所以似乎正在发生的事情是我的程序无法识别何时将节点设置为 nullptr...我不知道为什么会这样。每当我检查 if(node != nullptr) 时,它似乎都通过并直接进入语句。我这样说可能是错误的,但这就是我认为正在发生的事情……也许你会得出不同的结论。以下是您应该需要的所有代码,如果您需要我发布更多代码以便找到问题,请告诉我。

提前感谢您的帮助。

这是我的代码

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

这是一个 GDB 日志,记录了它的段错误位置

注意:调用此删除时列表为空。它应该认识到 head->next 是一个 nullptr,而不是试图将其数据与要删除的数据进行比较。

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)

节点类定义和构造函数

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

列表构造函数

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

最佳答案

我认为这是由打字错误引起的。

你写道:

   if(del = tail)
        tail = pre;

你的意思可能是:

   if(del == tail)
        tail = pre;

我看到的问题

  1. 这可能不是您的问题,但值得指出。你有:

    if(head->data == data){
    

    如果列表为空,即 head == nullptr,这将是一个问题。

  2. 构造函数中的代码不正确。你有:

    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. deleteNode 中的 while 循环需要仔细检查以确保您做的是正确的事情。

    你有:

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

    假设您的列表中有 25 个项目,给定的数据是列表中的第 5 个项目。此时,pre指向第4个节点,del指向第5个节点。然后你执行:

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

    然后你执行:

      if(del = tail)
    

    此语句将 del 指向列表的尾部——第 25 个节点。表达式 (del = tail) 的计算结果为 true。所以,你执行:

      tail = pre;
    

现在 tail 指向列表中的第 4 个节点。

然后你执行:

      delete del;

删除列表的第 25 个节点。

现在,列表是一个奇怪的状态。 tail 指向第 4 个节点。第25个节点已被删除,但第24个节点仍指向它。

关于c++ - 删除双向链表中的节点时发生段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23401544/

相关文章:

c++ - unsigned int 到 unsigned long long 定义明确吗?

c++ - 与已知图像匹配的局部二进制模式

c++ - Visual C++ 中的运算符重载?

c - 对字符串链表进行排序时出现运行时错误

java - 泛型的问题

c++ - vector 迭代编译成非常不同的指令

c - 为什么 feof() 中会出现段错误?

c++ - assert(pointer) 引发分段违规

c++ - 使用 find 函数时在 std::map 中获取 SIGSEGV

c - 链表循环迭代改变全局变量头