Почему я получаю ошибку сегментации при создании этого связанного списка? - PullRequest
0 голосов
/ 23 сентября 2018

Я очень плохо знаком с 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");
}

1 Ответ

0 голосов
/ 23 сентября 2018

Ваш head является локальным для функции add_to_list и будет уничтожен при выходе из функции управления add_to_list.

Также любые изменения, сделанные в head внутри add_to_list, не влияют на исходную головку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, &lst);

Другой вопрос:

char* word = ""; это будетсоздать word как указатель на неизменный строковый литерал.Изменение word содержимого scanf("%s",word); приведет к UB, и, поскольку каждый раз, когда вы передаете один и тот же указатель на add_to_list, каждый узел в списке будет указывать на один и тот же word.

. Возможно, вы захотитеобъявите его, как показано ниже.

char *word = malloc(256); Внутри цикла while и передайте его add_to_list.

...