为什么在打印链接列表的内容时出现细分错误?

时间:2019-04-02 02:15:47

标签: c linked-list segmentation-fault stack malloc

我正在尝试使用C中的链接列表来实现类似堆栈的结构。最终,它将从输入文件读取长度不同的字符串,因此需要动态内存。我在printList中的printf处遇到了分段错误,我不知道为什么。在推送中我也遇到了分段错误,但是我似乎已经解决了。如果不太明显,我的目的是仅将元素添加到列表的“顶部”。

#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();
}

2 个答案:

答案 0 :(得分:2)

为什么要在push()中复制到字符串末尾的1?另外,如果字符串太长,strncpy不会为您设置NUL。

真正的崩溃是在“ Head”创建中,即没有条目时的第一个if语句。它的下一个指针不会为NULL,因此在遍历最后一个条目时将遍历列表,因为它在列表末尾读取垃圾指针。

答案 1 :(得分:0)

它对我有用,因为迈克尔·德根(Michael Dorgan)问您为什么在字符串末尾再过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的需要。