C 管理链表内存

C 管理链表内存,c,memory-management,linked-list,C,Memory Management,Linked List,最近我经常使用C语言(我通常使用更高级的语言),在管理列表时遇到了问题 特别是,将节点添加到链接列表中。我经常以编写类似于下面的示例代码而告终。就我所见,它应该可以正常工作,但是没有新的节点附加到列表中 #include <stdio.h> #include <stdlib.h> typedef struct ListNode { struct ListNode* next; int data; } ListNode; ListNode* create

最近我经常使用C语言(我通常使用更高级的语言),在管理列表时遇到了问题

特别是,将节点添加到链接列表中。我经常以编写类似于下面的示例代码而告终。就我所见,它应该可以正常工作,但是没有新的节点附加到列表中

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

typedef struct ListNode {
    struct ListNode* next;
    int data;
} ListNode;

ListNode* createListNode(int data){
    ListNode* node = (ListNode*)malloc(sizeof(ListNode));
    node->data = data;
    node->next = NULL;
    return node;
}

void addListNode(ListNode* list, ListNode* newListNode){
    ListNode* current;

    if(list == NULL){
        list = newListNode;
    }else{
        current = list;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = newListNode;
    }
}

int main(void) {
    int ii;
    ListNode* list = NULL;
    ListNode* newListNode = NULL;
    int fakeData[3] = {1, 2, 3};

    for(ii=0; ii<=2; ii++){
        newListNode = createListNode(fakeData[ii]);
        addListNode(list, newListNode);
    }

    printf("%d", list->data);
    printf("%d", list->next->data);
    printf("%d", list->next->next->data);

    return 0;
}
它很好用。为什么会这样

我可以这样做,但我不想让特定于链表的代码到处浮动

很明显,我遗漏了一些非常基本的东西

void addListNode(ListNode* list, ListNode* newListNode)
这应该是ListNode**list,否则函数实际上不会更改它的值。 列表=newListNode;命令在函数之外不会有任何效果


使用ListNode**list,当您想更改该值时,只需说*list=newListNode

这似乎解决了问题。为什么我要使用双指针?列表被定义为普通指针,这还不够。
main()
ListNode*list
的副本传递给了
addListNode()
,这将无法修改原始副本。传递双指针类似于通过引用传递
ListNode*list
。另一个解决方案是将创建全新列表和向列表中添加更多成员的角色分开。如果列表ptr为空,则让
main()
调用
createListNode()
,否则使用
addListNode()
添加更多项。因为您希望更改指针本身,而不仅仅是它指向的值。为此,您需要指针的地址,因此它需要是ListNode**而不是ListNode*
void addListNode(ListNode* list, ListNode* newListNode)