【问题标题】:Repeated Segmentation Fault while deleting from a Linked List in C从 C 中的链表中删除时出现重复分段错误
【发布时间】:2019-11-14 23:13:36
【问题描述】:

对于一个作业,我们被告知要创建一个字典抽象数据类型 (ADT),它基于 C 中的链表结构。

从我使用所需功能的所有测试中

尺寸 插入(使用尾节点在尾部完成) 删除 makeEmpty

我编写的客户端测试了所有这些,我没有遇到任何问题。

但是当使用提供的评分脚本时,我会遇到分段错误。

脚本将一千个条目添加到“字典”中

做了一些不相关的步骤

删除从901到1000的条目,表示从链表的中间删除

我到达这一点没有问题,但下一部分会导致段错误

当脚本尝试从 900 向下删除时,在 772 处我总是遇到 seg 错误

我尝试通过向“字典”添加 10 个条目来重新创建一个较小的样本

删除 9 和 10

然后尝试从 8 下删除,我没有遇到同样的问题?

这是我的删除功能,任何帮助将不胜感激

void delete(Dictionary D, char* key){
   Node N;
//Nodes are pointers to NodeObj's which are structs that have a key,a value, and a Node which points to //the next in the list
   Node P = NULL;      

   N = find(D, key);//returns the desired Node


   if(N == D->head){//D-> head is a field in a Dictionary struct which is a Node that has no value and //points to the first NodeObj in the list

      D->head = N->next;
      if(N == D->tail)D->tail = NULL;//D->tail is the same thing as head, but pointing to the last //NodeObj

   }else if(N == D->tail){

      D->tail = findPreviousNode(D, N->key);

   }else{

      P = findPreviousNode(D, N->key);
      P->next = N->next;

   }

   N->next = NULL;
   freeNode(&N);
   N = NULL;
   D->numItems--;



}

我已经省略了一些先决条件检查,以确保没有任何条件被触发导致问题

编辑:

我想我可能遗漏了一些重要信息。

在我的程序中,Dictionary 是指向 DictionaryObj 的指针的 typedef。其中包含头节点、尾节点及其大小的字段。

Node 是指向 NodeObj 的指针,它具有键、值和 Node 字段,以便指向链表中的下一个 NodeObj。

所以 delete() 被传递了一个指向 DictionaryObj 的指针,它有一个 head 字段 指向第一个 NodeObj,从他们可以跟随每个 NodeObj 的下一个 字段。

我以为我已经涵盖了删除 DictionaryObj 的头字段指向的节点时的情况,方法是重新分配头字段以指向列表中的下一个节点,该节点是通过跟随该 NodeObj 中的节点指针获得的。

【问题讨论】:

  • 您需要查看:Is it a good idea to typedef pointers?。您的delete 函数必须传递原始指针的地址,而不仅仅是指向头的指针。这样,如果您删除第一个节点,您可以更新原始指针以保存新 head 节点的新地址。 Dictionary 中的指针的 typedef 部分掩盖了该问题。 Singly Linked List of Integers (example) 可能会有所帮助。
  • @DavidRankin-ReinstateMonica,很遗憾我没有完全理解你的建议,我觉得这可能与我缺乏解释有关。我已经编辑了原始帖子以添加更多可能相关的细节。
  • 如果您进一步查看您的代码,您可能有一个typedef stuct node* Dictionary;。因此,您的链表中节点的类型实际上类似于struct node* 而不是Dictionary(这只是一个别名)。在您的delete 函数中,您必须传递struct node **DDictionary *D 才能传递您的head 节点的实际地址(例如delete (&head, key),而不是delete (head, key)。这样您的delete 函数接收head 节点的实际地址,而不是指针的副本在上面的链接中阅读我的答案...
  • 为了提供明确答复,请提供A Minimal, Complete, and Verifiable Example (MCVE)

标签: c dictionary linked-list segmentation-fault abstract-data-type


【解决方案1】:

我遇到的问题是,当我从链接列表的末尾删除时,我正确地将字典的尾节点指向要删除的节点的前一个节点。但我并没有确保将前一个节点的“下一个”值指向 NULL,因为在它之后不会有任何东西。

应该是的

}else if(N == D->tail){

      P = findPreviousNode(D, N->key);
      D->tail = P
      P->next = NULL;

   }else{

【讨论】:

    猜你喜欢
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-28
    • 2015-09-17
    • 1970-01-01
    • 2017-05-22
    • 2013-04-11
    相关资源
    最近更新 更多