c - C 中的链表 – 方法

标签 c dynamic data-structures linked-list doubly-linked-list

假设我们有双向链表的节点

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

typedef struct Node {
    int value;
    struct Node* next;
    struct Node* prev;
} Node;

typedef struct LinkedList {
    Node *first;
    Node *last;
} LinkedList;

void initList(LinkedList* l) {
    l->first = NULL;
    l->last = NULL;
}

我必须编写方法,该方法将具有给定值的新节点插入到列表末尾并返回指向新节点的指针。我的尝试如下:

Node *insert(LinkedList *list, int value) {

    Node node;
    node.value = value;
    node.prev = list->last;
    node.next = NULL;

    if (list->last != NULL){
        (list->last)->next = &node;
    }else{
        list->first = &node;
        list->last = &node;
    }

    return &node;
}

看起来,在空列表中插入是有效的,但对于非空列表则不然。

(有实现测试,它告诉我插入是否成功。我可以发布它们的代码,但我认为这并不重要)。

请问哪里有错误?

日志中有警告(第51行是带有'return &node'的)

C:\...\main.c|51|warning: function returns address of local variable [-Wreturn-local-addr]|

这个问题严重吗?以及如何删除它?


谢谢您的回答,但我认为非空列表仍然存在问题,因为根据测试,这失败了:

void test_insert_nonempty(){
    printf("Test 2: ");

    LinkedList l;
    initList(&l);

    Node n;
    n.value = 1;
    n.next = NULL;
    l.first = &n;
    l.last = &n;

    insert(&l, 2);

    if (l.last == NULL) {
        printf("FAIL\n");
        return;
    }
    if ((l.last->value == 2) && (l.last->prev != NULL)) {
        printf("OK\n");
        free(l.last);
    }else{
        printf("FAIL\n");
    }
}

最佳答案

Node 节点; 是函数 insert 中的局部变量。一旦您的函数终止并且不再定义,它就会被“销毁”。返回指向函数局部变量的指针是未定义的行为。您必须分配动态内存。动态分配的内存会被保留,直到您释放它为止:

Node *insert(LinkedList *list, int value) {

    Node *node = malloc( sizeof( Node ) ); // allocate dynamic memory for one node
    if ( node == NULL )
        return NULL; // faild to allocate dynamic memory

    node->value = value;
    node->prev = list->last;
    node->next = NULL;

    if ( list->first == NULL )
        list->first = node;      // new node is haed of list if list is empty
    else // if ( list->last != NULL ) // if list->first != NULL then list->last != NULL
        list->last->next = node; // successor of last node is new node
    list->last = node;           // tail of list is new node

    return node;
}

请注意,为了避免内存泄漏,当您销毁列表时,您必须释放列表中的每个节点。

关于c - C 中的链表 – 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35680755/

相关文章:

c - 在 c 中使用 fork() 和信号处理进行编程

c# - 如何使用 C# 在 UWP 中制作 ItemsWrapGrid?

javascript - 使用选择器再次调用 data() 时,动态创建元素并附加数据的 JQuery 不返回值?

python - 如何在 django/python 中动态创建对象?

c++ - Trying Favorite Tries : Radix, 后缀,和哈希!甚至三元组,天哪!

javascript - 如何在 Javascript 中将数组值映射到对象内的数组?

c - 在 C 中没有匹配项时在字符串中插入一个字符

c - 在 procfs.h 中找不到 pstatus_t (LINUX)

c - 当我尝试使用指针访问结构时出错

java 数组双端队列大小与性能