【问题标题】:Segmentation fault in a C function to concatenate two linked lists连接两个链表的 C 函数中的分段错误
【发布时间】:2014-03-10 18:48:03
【问题描述】:

我正在尝试编写一个函数,将两个列表连接起来形成一个新列表,其中包含 list1 和 list2 中所有节点的副本,并返回一个指向这个新列表的指针。

Node *concat(Node *list1, Node *list2) {
  Node *head, *ptr;
  if (list1==NULL) {
    if (list2!=NULL)
      return copy(list2); 
/*copy refers to a function that copies a list & returns pointer to new list*/
    else
      return NULL;
  }
  else if (list2==NULL) {
    if (list1!=NULL)
      return copy(list1);
    else
      return NULL;
  }
  else {
  while (list1 != NULL) {
    if (head==NULL) {
      head=newNode(list1->airport);
      ptr=head;
    }
    else {
      Node *n=newNode(list1->airport);
      ptr->next=n;
      ptr=ptr->next;
    }
    list1=list1->next; }
  while (list2 != NULL) {
    Node *n1=newNode(list2->airport);
    ptr->next=n1;
    ptr=ptr->next;
    list2=list2->next;
  }
  }
  return head;
}

当我使用打印的程序测试此功能时

  • 连接到 NULL 列表 2 的单节点列表 1
  • 一个 NULL list1 连接到一个单节点 list2
  • 节点列表 (list1) 连接到单节点列表 2

我遇到了分段错误。

我在函数中找不到分段错误的来源,尽管我相信它在第一部分,在 while (list1 != NULL) 之前,因为如果两个列表都不是 NULL,它似乎可以工作。

【问题讨论】:

  • 你永远不会将 head 初始化为 NULL;
  • 既然你已经有了copy(),那么在list1list2的每一个上调用copy()不是更简单,然后将前者的末尾加入到开头后者?
  • 总是初始化Node *head = NULL; Node *ptr = NULL;
  • 你的意思是当两个列表都不为空时代码工作正常?并在列表之一为空时给出分段错误?
  • 如果您实现copy()-函数的方式是在将空指针传递给它时返回空指针,则可以大大简化此函数。

标签: c linked-list segmentation-fault concatenation


【解决方案1】:

无法为您已经收到的 cmets 和答案添加太多内容,但已将 cmets 放入您的代码中以帮助您了解崩溃的原因。

Node *concat(Node *list1, Node *list2) {

/* These are uninitialised variables, which basically means they will 
 * take the whatever random values that are on the stack. It is unlikely
 * that the values will be NULL.
 */
Node *head, *ptr;  

if (list1==NULL) {
  if (list2!=NULL)
    return copy(list2); 
    /*copy refers to a function that copies a list & returns pointer to new list*/
  else
    return NULL;
}
else if (list2==NULL) {
  if (list1!=NULL)
    return copy(list1);
  else
    return NULL;
}
else {
while (list1 != NULL) {

/* When you get here, head isn't NULL so you go to the else block */

if (head==NULL) {
  head=newNode(list1->airport);
  ptr=head;
}
else {
  Node *n=newNode(list1->airport);

  /* Bang! Highly likely to crash here, as you are dereferencing a 
   * random value (in ptr) as though it is a valid pointer. 
   */
  ptr->next=n;
  ptr=ptr->next;
}
list1=list1->next; 
}
while (list2 != NULL) {
  Node *n1=newNode(list2->airport);
  ptr->next=n1;
  ptr=ptr->next;
  list2=list2->next;
}
}
return head;
}

【讨论】:

    【解决方案2】:

    由于您已经有一个复制函数,它创建新列表并返回头点,因此可以如下修改程序(如果将 NULL 输入传递给复制函数,则它应该返回 NULL,这个假设成立)

    节点 *concat(节点 *list1, 节点 *list2) {

       Node *head = NULL, *ptr = NULL;
    
       if(list1 != NULL)
       {
    
          head = copy(list1);
       }
    
       if(list2 != NULL)
       {
          if(NULL == head)
          {
            return copy(list2);
          }
       }
    
       ptr = head;
    
       while(ptr->next != NULL)
       {
          ptr = ptr->next;
       }
    
       ptr->next = copy(list2);
       return head;
    

    }

    【讨论】:

      猜你喜欢
      • 2020-06-19
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      • 2012-06-12
      • 2020-09-10
      • 1970-01-01
      • 1970-01-01
      • 2020-03-17
      相关资源
      最近更新 更多