简体   繁体   English

C中的链接列表–方法

[英]Linked list in C – methods

Suppose we have doubly linked list of nodes 假设我们有双重链接的节点列表

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

and I have to code method, which inserts a new node with given value to the end of the list and returns a pointer to the new node. 我必须编写代码方法,该方法将具有给定值的新节点插入列表的末尾,并返回指向该新节点的指针。 My attempt follows: 我的尝试如下:

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;
}

It seems, that insertion in the empty list works, but it doesn't for a non-empty one. 看来,在空列表中插入是可行的,但对于非空列表则无效。

(There are implementation tests, which tell me if an insertion was successful or not. I can post the codes of them, but don't think it's important). (有一些实现测试,可以告诉我插入是否成功。我可以发布它们的代码,但是并不重要)。

So please, where are the mistakes? 那么,请问错误在哪里?

There is a warning in the log (the 51st line is that with 'return &node') 日志中有一个警告(第51行是带有“ return&node”的警告)

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

Is that serious problem? 那是个严重的问题吗? And how to remove it? 以及如何将其删除?


Thank you for the answers, but I think there is still a problem with non-empty lists, because according to the test, this fails: 感谢您的回答,但我认为非空列表仍然存在问题,因为根据测试,此操作失败:

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 node; is a local variable in your function insert . 是函数insert的局部变量。 It is "destroyed" as soon as your function terminates and is not longer defined. 一旦您的函数终止并且不再定义,它就会被“销毁”。 Returning a pointer to local variable of a function is undefined behavior. 将指针返回到函数的局部变量是未定义的行为。 You have to allocate dynamic memory. 您必须分配动态内存。 Dynamically allocate memory is reserved until you free it: 动态分配内存将保留,直到您free它:

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;
}

Note to avoid memory leaks you have to free each node of the list, when you destroy the list. 请注意,为避免内存泄漏,销毁列表时必须free列表的每个节点。

You are returning address of non-static local variable which will vanish on returning from function, and dereferencing the address after returning from the function invokes undefined behavior . 您要返回的非静态局部变量的地址在从函数返回时将消失,从函数返回后取消引用该地址将调用未定义的行为

You have to allocate some buffer and return its address. 您必须分配一些缓冲区并返回其地址。

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

    Node *node = malloc(sizeof(Node));
    if (node == NULL) return NULL;
    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;
}

You have to allocate the new node dynamically. 您必须动态分配新节点。

Otherwise variable node in your function 否则函数中的变量node

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

    Node node;
    //...

is a local variable of the function that will not be alive after exiting the function. 是该函数的局部变量,退出该函数后将不活动。 As result any pointer to the variable used to access it will be invalid. 结果,用于访问该变量的任何指针都将无效。

The function can look like 该功能可以看起来像

Node * insert( LinkedList *list, int value ) 
{
    Node *node = malloc( sizeof( Node ) );

    if ( node != NULL )
    {
        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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM