使用空链表避免分段错误

Avoid Segmentation Fault with Empty Linked List

我在 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

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

如果链表为空,则头节点始终为空。在您的函数中,您检查空节点的头部和尾部元素。这就是为什么你会出现分段错误。

试试下面的函数

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

我认为您试图在单行函数调用中做太多事情。 front(Node)->value 总是会尝试取消引用从该函数返回的任何内容,即使它是 NULL,因此当列表为空并且它 returns NULL 时会出现段错误.您需要拆分该行.. 首先从对 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
 }

可能有一种更聪明的单线方式,但如果您遇到困难并且不受严格的线路要求限制,这真的值得吗?