【问题标题】:Avoid Segmentation Fault with Empty Linked List使用空链表避免分段错误
【发布时间】:2016-03-02 04:52:12
【问题描述】:

我有一个 C 语言列表,其中包含以下数据结构:

typedef struct node{
    int in_id;
    struct node *next; 
} Node;

typedef struct List{
    Node* head;
    Node* tail;
}List;

如果列表被占用,我的查看列表前面的功能可以正常工作,但是,如果列表为空并且我在列表中查看,我会收到分段错误。这是完全可以理解的。但是,我一直在尝试想一种方法来防止这种情况或规避分段错误。

Node* front(List *q){
Node *temp;
temp = NULL;
if(q->head == NULL && q->tail == NULL){
    printf("front function: this is empty \n");
    return temp;
}
else{
    temp = q->head;
    return temp;
    }
}

第一个想法是,如果我需要在 if(front(Node)->value == x) 中使用 front,如果它为空,我会收到分段错误。但是,我通过在前面放置一些我需要测试的东西来缩短它,if( something == TRUE && front(Node)->value == x)。 我还考虑做的是malloc() 一些动态内存到前面的temp,并分配我正在测试的相关字段,如果head && tail == NULL 是假的,我知道该值是假的。但是,我觉得这是内存泄漏,因为我无法free() temp

我有没有更好的方法来处理窥视这个队列并且如果它是空的则不会出现分段错误?

【问题讨论】:

  • TL;DR if(q == NULL) { /* List is empty */ return NULL;}
  • if(!isEmpty(aList) && front(aList)->value == x)
  • @BLUEPIXY - 这就是我将其短路并避免分段错误的方法。但是有没有办法处理front(),这样如果我调用它并且它是空的,我就不会遇到分段错误?
  • front 可能必须返回一个NULL,所以不能单独使用front(aList)->value
  • @BLUEPIXY - 有道理,我认为真的没有办法不单独使用它。谢谢。

标签: c list pointers queue


【解决方案1】:

我认为您试图在单行函数调用中做太多事情。 front(Node)->value 总是会尝试取消引用从该函数返回的任何内容,即使它是 NULL,因此当列表为空并返回 NULL 时会出现 seg 错误。您需要拆分该行。首先从对front(...) 的调用中检索指针,然后检查它是否有NULL,如果不是NULL,则继续取消引用:

 Node* temp = front(list);
 if (temp != NULL)
 {
   // proceed with dereference
   if (temp->value == x) // this won't seg fault, do whatever with it
   {
      // ...
   }
 }
 else
 {
   // print error or do nothing
 }

可能有一种更聪明的方法来单行,但如果你被卡住并且不受严格的行要求的限制,那真的值得吗?

【讨论】:

  • 如果您决定将其保留为 1-liner,那么您可以执行if(front(list) && front(list)==x){ 之类的操作。请务必注意此处的操作顺序,必须在取消引用之前检查来自front 的有效返回,否则您将遇到与以前相同的问题。而且我敢打赌,这将被编译成与原始答案几乎完全相同的内容,因此它不会为您带来任何实用的东西。但总的来说,养成从任何可能以一种或另一种方式返回的函数检查 NULL 的习惯。它会让你头疼。无论哪种方式都很好 IMO。
【解决方案2】:

如果链表为空,则头节点始终为空。在您的函数中,您检查空节点的头尾元素。这就是你得到分段错误的原因。

试试下面的函数

  Node* front(List *q){
  Node *temp;
  temp = NULL;
  if(q == NULL){
     printf("front function: this is empty \n");
     return temp;
   }
 else{
   temp = q->head;
    return temp;
   } 
 }

【讨论】:

  • 这不太行,我仍然遇到分段错误。
  • 然后你检查你的链表是否正确获取表格
  • 它正确地获取了前面...但是当它返回 NULL 并尝试引用它时...这是一个分段错误。
猜你喜欢
  • 2021-03-31
  • 1970-01-01
  • 1970-01-01
  • 2020-04-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-16
  • 2018-02-18
  • 1970-01-01
相关资源
最近更新 更多