如何修复 C 代码中的 SIGSEGV(分段错误)?

How can i fix SIGSEGV (segmentation fault) in my C code?

提问人:weuoimi 提问时间:11/17/2023 最后编辑:weuoimi 更新时间:11/17/2023 访问量:44

问:

我正在用 C 编写一个程序,该程序读取用括号分隔的文件中的句子,将它们解释为“房间”(不要问),并将它们作为动态分配的节点附加到动态分配的单向链表结构中。GDB 在 add_to_list(const room_t *room, list *list) 函数中标记了行

 current->next = createnode(room);

行作为导致 SIGSEGV(地址边界错误)的行

代码如下:

void
create_room(char *text, list *list)
{
  unsigned int index;
  color_t color;
  char *description;

  parse_curly_brackets(text, &index, &color);

  room_t *new_room = (room_t *)malloc(sizeof(room_t));
  new_room->index = index;
  new_room->color = color;

  char *ptr = strchr(text, '}');
  if (ptr != NULL)
    {
      ptr = strchr(ptr + 1, '}');
      if (ptr != NULL)
        {
          ptr++; 
          while (*ptr != '\0' && (*ptr == ' ' || *ptr == '\n')) 
            ptr++;

          description = ptr;
          new_room->description = (char *)malloc(strlen(description));
          strcpy(new_room->description, description);
        }
      else
        {
          printf("Second closing curly brace not found\n");
          free(new_room);
          return;
        }
    }
  else
    {
      printf("Closing curly brace not found\n");
      free(new_room);
      return;
    }

  add_to_list(new_room, list);
}

node_t
*createnode (const room_t *room)
{
  node_t *newnode = malloc(sizeof(node_t));

  if (!newnode)
    {
      return NULL;
    }
  
  newnode->data = room;
  newnode->next = NULL;

  return newnode;
};

void
add_to_list (const room_t *room, list *list)
{
  node_t *current = NULL;

  if (list->head == NULL)
    {
      list->head = createnode(room);
    }

  else
    {
      current = list->head;
      while (current->next != NULL)
        {
          current = current->next;
        }
      current->next = createnode(room);
    }
}

以下是结构:

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

typedef
struct Node
{
  const struct Room *data;
  struct Node *next;
} node_t;

typedef
struct Room
{
  unsigned int index;
  color_t color;
  list objects;
  char *description;  /* the description buffer that will be written from the file */
  
} room_t;

我试图使一些函数参数 const 提供只读访问权限,但我不确定我是否让它变得更糟。我已经检查了是否正确分配了内存,但找不到导致问题的原因。所以我希望你会!您可以在此处熟悉完整的代码: https://github.com/stakhovyak/agorica 您可以检查 description.org 文件以了解我尝试在create_room函数中执行的操作

c gcc 分段故障

评论

1赞 Klaus 11/17/2023
开始使用调试器的好日子!
0赞 Some programmer dude 11/17/2023
在 C 中,你不应该强制转换 malloc 的结果
0赞 Nate Eldredge 11/17/2023
调试器,是的,加上内存检查工具,如 AddressSanitizer 或 valgrind。
0赞 weuoimi 11/18/2023
我已经使用 Valgrind 和 GDB 来测试我的程序并调试它们,问题是这是我的第一个大项目,顺便说一句,Valgrind 没有问题,我只是从头开始重写了一些代码,它运行良好

答:

1赞 Sergej Christoforov 11/17/2023 #1

您不为 null 终止符分配空间:

          new_room->description = (char *)malloc(strlen(description));
          strcpy(new_room->description, description);

您需要再分配一个字节:

          new_room->description = malloc(strlen(description) + 1);
          strcpy(new_room->description, description);

另外,不要强制转换 的结果。malloc

评论

0赞 weuoimi 11/17/2023
不幸的是,这无济于事。但感谢您的建议!