【问题标题】:Why does printf cause a segfault in a linked list?为什么 printf 会导致链表中的段错误?
【发布时间】:2021-01-27 20:33:39
【问题描述】:

我的代码采用一串由空格分隔的整数并从中构建一个链表,但 -1 除外。为什么打印nextNode -> data 会导致段错误?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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

void build_linked_list(Node **head_ptr) {
  char *string = malloc(1028);
  char *p = string, *found = string;
  Node *nextNode = NULL;
  if (fgets(string, 1028, stdin) != NULL) {
    while ((found = strsep(&p, " \n")) != NULL) {
      if (strcmp(found, "-1") == 1) {
        Node *node = malloc(sizeof(Node));
        node->data = atoi(found);
        node->next = nextNode;
        nextNode = node;
      }
    }
  }
  *head_ptr = nextNode;
  printf("%i\n", nextNode->data); //error here
  free(string);
}

int main() {
  Node *head = NULL;
  build_linked_list(&head);
  return EXIT_SUCCESS;
}

【问题讨论】:

  • 你在阅读nextNode-&gt;data之前没有检查nextNode != NULL
  • 仅供参考,如果两个字符串不匹配,strcmp 将返回非零(负值或正值),因此您不应测试值 1。
  • 我能看到的嫌疑人是strcmp(found, "-1") == 1。你真的关心字符串相对于“-1”的字典顺序吗?如果你只是想检查它不是“-1”,条件应该是strcmp(found, "-1") != 0

标签: c linked-list segmentation-fault


【解决方案1】:

无论如何,您都尝试打印nextNode-&gt;data,但如果nextNodeNULL 怎么办?试图访问无效指针的成员将导致分段错误。

详细说明:

  1. 你初始化指向NULL的指针

    Node *nextNode = NULL;
    
  2. 您更新指针,但仅在某些条件下

    if (fgets(string, 1028, stdin) != NULL) {
      while ((found = strsep(&p, " \n")) != NULL) {
        if (strcmp(found, "-1") == 1) {
          /* ... */
          nextNode = node;
        }
      }
    }
    
  3. 您打印该字段

     printf("%i\n", nextNode->data); //error here
    

    但如果条件不满足,指针可能仍为NULL

要解决此问题,请在取消引用之前检查指针:

if( nextNode )
{
    printf("%i\n", nextNode->data);
}
else
{
    printf("NULL nextnode\n");
}

【讨论】:

    【解决方案2】:

    在阅读nextNode-&gt;data之前,您没有检查nextNode != NULL

    strcmp(3) - Linux manual page

    strcmp() 返回一个表示比较结果的整数, 如下:

       · 0, if the s1 and s2 are equal;
    
       · a negative value if s1 is less than s2;
    
       · a positive value if s1 is greater than s2.
    

    当两个字符串不同时从strcmp() 返回的内容不一定是1,所以strcmp(found, "-1") == 1 是一个错误的表达式来检查found 是否不是-1

    您的环境中的strcmp() 似乎返回了1 以外的内容,并且没有执行任何插入,因此NULLnextNode-&gt;data 处取消引用,调用了分段错误。

    试试这个:

    void build_linked_list(Node **head_ptr) {
      char *string = malloc(1028);
      char *p = string, *found = string;
      Node *nextNode = NULL;
      if (fgets(string, 1028, stdin) != NULL) {
        while ((found = strsep(&p, " \n")) != NULL) {
          /* use != 0 to check string inequility and avoid processing empty string */
          if (strcmp(found, "-1") != 0 && strcmp(found, "") != 0) {
            Node *node = malloc(sizeof(Node));
            node->data = atoi(found);
            node->next = nextNode;
            nextNode = node;
          }
        }
      }
      *head_ptr = nextNode;
      if (nextNode != NULL) { /* check if nextNode is not NULL */
        printf("%i\n", nextNode->data); //error here
      }
      free(string);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-06
      • 2011-07-07
      • 1970-01-01
      • 2015-06-29
      • 1970-01-01
      • 1970-01-01
      • 2015-09-03
      • 1970-01-01
      相关资源
      最近更新 更多