【问题标题】:Why am I getting a segmentation fault on this linked list creation?为什么我在创建此链接列表时遇到分段错误?
【发布时间】:2018-09-23 19:31:59
【问题描述】:

我对 C 非常陌生,我不明白代码中出现分段错误的位置。我只是想创建一个链接列表,它将作为哈希表的类型单元。我知道我可能没有在我应该使用的地方使用 malloc。主要功能将运行,但只要我添加一个项目,我就会遇到分段错误。

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


typedef struct word_link
{
    char* val;
    struct word_link * next;
} word_link;

void add_to_list(char* word, word_link *head);

void add_to_list(char* word, word_link *head){

  int i;
  word_link * temp = NULL;
  word_link * p = NULL;

  temp = (word_link*)malloc(sizeof(word_link));
  temp->val = word;
  temp->next = NULL;

  if(head == NULL){
    head = temp;
  } else {
    p = head;
    while(p->next != NULL){
      p = p->next;
    }
    p->next = temp;
  }
}
void main() {

  int i = 0;
  struct word_link *lst = malloc(sizeof(word_link));
  char* word = "";
  while(i == 0){
  printf("what to add?  ");
  scanf("%s",word);
  add_to_list(word, lst);
  printf("continue?  ");
  scanf("%d", i);
  }
  printf("%s", lst->val);
  printf("%s", "asdf;kl");
}

【问题讨论】:

  • head = temp; 不会更改 lst 中的 main()。另请查看char* word = ""; ... scanf("%s",word);。也许还有其他问题。强烈建议在启用所有警告的情况下进行编译。良好的预期反馈比在 SO 上发布要快。
  • 有许多错误强烈表明您不熟悉 C 的内存模型(以及字符串和按值调用参数等)。首先,您可能会发现以下有用:内存调试器(例如,valgrind)、静态代码分析器(例如,clang-check、cppcheck 等)、编译器标志 -Wall -Wextra。尽管如此,他们都不能替代花时间阅读一本关于 C 编程的书。
  • char* word = "";只读内存中创建一个空字符串字符串文字scanf("%s",word); 在您尝试写入word(很可能是SegFault)时调用Undefined Behavior 您在哪里为temp-&gt;val 分配存储空间?您不在 C 中分配字符串,但必须使用 strcpy(您可以分配指针,但如果 namemain() 中发生变化,您将更改 val-&gt;word - 为 @ 分配存储空间后需要一个副本987654334@.
  • 不要将调用结果转换为 malloc()(或 calloc()realloc())——这是不必要的,如果你没有正确的原型,它会掩盖一个非常真实的错误范围。

标签: c segmentation-fault


【解决方案1】:

你的headadd_to_list 函数的本地函数,一旦控制退出add_to_list 函数就会被销毁。

此外,对 add_to_list 内部的 head 所做的任何更改都不会影响原始头部 lst

解决方案:

您可以将原始头部的引用传递给插入,以保留在add_to_list 中所做的更改,如下所示。

void add_to_list(char* word, word_link **head);

void add_to_list(char* word, word_link **head){    
  int i; 
  word_link * temp = NULL;
  word_link * p = NULL;

  temp = (word_link*)malloc(sizeof(word_link));
  if (temp == NULL) return;

  temp->val = word;
  temp->next = NULL;

  if(*head == NULL){
    *head = temp;
  } else {
    p = *head;
    while(p->next != NULL){
      p = p->next;
   }
    p->next = temp;
  }
}

然后你拨打add_to_list如下。

add_to_list(word, &amp;lst);

另一个问题:

char* word = ""; 这将创建word 作为指向不可变字符串文字的指针。修改word 内容scanf("%s",word); 将导致UB,因为每次您将相同的指针传递给add_to_list 时,列表中的每个节点都将指向相同的word

你可能想如下声明它。

char *word = malloc(256); 在 while 循环中并将其传递给 add_to_list

【讨论】:

  • 不要将调用结果转换为malloc()(或calloc()realloc())——这是不必要的,如果你没有合适的原型,它会掩盖一个非常真实的错误范围。
猜你喜欢
  • 1970-01-01
  • 2021-10-19
  • 1970-01-01
  • 2016-08-03
  • 2020-08-03
  • 2021-02-14
相关资源
最近更新 更多