C语言 地址边界错误-为什么我的链表中的节点不能正确添加?

lf5gs5x2  于 2023-01-29  发布在  其他
关注(0)|答案(1)|浏览(119)

我试图用C实现一个链表,但是我似乎不知道如何将元素添加到链表中。

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

typedef struct element {
    int value;
    struct element* next;
} element;

typedef struct list {
    element* head;
} list;

list* createList(int headValue) {
    list* L = malloc(sizeof(list));
    L->head = malloc(sizeof(element));
    L->head->value = headValue;
    L->head->next = NULL;
    return L;
}

// Returns the new length of the list
int appendToList(list* L, int value) {
    element* first = L->head;
    element* current = first;
    int length = 1;
    
    if (first == NULL) {
        printf("first is NULL\n");
        exit(2);
    }
    while (current != NULL) {
        current = current->next;
        length++;
    }
 
    current = malloc(sizeof(element));
    current->next = NULL;
    current->value = value;
    length++;

    return length;
}

// returns the value at index N (zero based)
//
// If the list has < N elements, returns -1 
int getAtIndexN(list* L, int N) {
    element* current = L->head;
    for (int i=0; i<N; i++) {
        if (current->next == NULL) {
            printf("unable to get to index %d\n", i+1);
            exit(1);
        }
        current = current->next;
    }
    return current->value;
}

int main(int args, char** argv) {
    int initvalues[] = {1,3,4,4};
    list* L = createList(5);
    for (int i=0; i<4; i++) {
        appendToList(L, initvalues[i]);
    }
    
    printf("element at index 1 has value %d\n", L->head->next->value);
    return 0;
}

我调用了appendToList 4次,以便将initvalues中的值追加到列表中,但似乎只有列表的头部被正确添加到列表中。main中的printf导致'./a.out' terminated by signal SIGSEGV (Address boundary error)。我不确定问题是出在appendToList还是其他地方。

jgovgodb

jgovgodb1#

在循环while (current != NULL)中,current最终将为null,并且您已经丢失了对原始列表的引用,接下来的所有操作,对current?的分配和赋值都是孤立发生的,除了泄漏内存之外没有任何影响。
看起来while (current != NULL) {应该是while (current->next != NULL) {,但是还有更多的事情需要修复...比如current = malloc(sizeof(element));应该是current->next = malloc(sizeof(element));等等。
PS:IMO createList在列表中添加第一个节点是一个糟糕的设计。它应该只创建一个空列表,即L-〉head = NULL。换句话说,你的代码应该IMO能够处理一个空列表。你当前的代码不允许这样做。

相关问题