#c #linked-list #segmentation-fault #stack #malloc
#c #связанный список #ошибка сегментации #стек #malloc
Вопрос:
Я пытаюсь реализовать структуру в стиле стека, используя связанный список в C. В конечном итоге он будет считывать строки различной длины из входного файла, следовательно, потребность в динамической памяти. Я получаю ошибку сегментации в printf в printList и не могу понять, почему. Я также получал ошибки сегментации в push ранее, но, похоже, я их исправил. В случае, если это не очевидно, мое намерение состоит в том, чтобы добавлять элементы только в «верхнюю» часть списка.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void* emalloc(size_t n);
typedef struct node {
struct node* next;
char* word;
} node;
node* head = NULL;
void* emalloc(size_t n) {
void* p;
p = malloc(n);
if(p == NULL) {
fprintf(stderr, "Failed to allocate memory.");
exit(1);
}
return p;
}
void push(char* w) {
if(head == NULL) {
head = (node*) emalloc(sizeof(node));
head->word = (char*) emalloc(strlen(w) * sizeof(char) 1);
strncpy(head->word, w, strlen(w) 1);
printf("Pushed a word to head.");
return;
}
node* newnode = (node*) emalloc(sizeof(node));
newnode->word = (char*) emalloc(strlen(w) * sizeof(char) 1);
strncpy(newnode->word, w, strlen(w) 1);
newnode->next = head;
head = newnode;
}
void printList() {
node* cur = head;
if(cur == NULL || cur->word == NULL) printf("Whoops!");
while(cur != NULL) {
printf(cur->word);
cur = cur->next;
}
}
/*
* The encode() function may remain unchanged for A#4.
*/
void main() {
char word[20] = "Hello world";
//push("Hello",head);
//push("World",head);
//push("!",head);
push(word);
printList();
}
Ответ №1:
Зачем копировать в 1 последний конец строки в push()? Кроме того, если строка слишком длинная, strncpy не обнулит ее для вас.
Однако настоящая ошибка заключается в создании «Head», первом операторе if, когда записей не существует. Он не обнуляет свой следующий указатель, поэтому обход списка будет прерван при последней записи, поскольку он считывает указатель мусора в конце списка.
Ответ №2:
у меня это сработало, поскольку Майкл Дорган спросил, почему вы пропустили 1 байт после конца строки.
Я рекомендую использовать что-то вроде :
int len =strlen(w)
перед
node* newnode = (node*) emalloc(sizeof(node));
newnode->word = (char*) emalloc(len * sizeof(char));
strncpy(newnode->word, w, len)[len]=0;
newnode->next = head;
эта временная переменная устраняет необходимость использования strlen в этих местах.