双链表改进

问题描述 投票:0回答:1

如果有任何想法可以提高我的 API 质量,我将不胜感激。提前致谢。

int ll_create(linked_list_p list, void (*print_data)(uint8_t)) {
    if (list == NULL) {
        list = calloc(1, sizeof(linked_list_p));
        return 0;
    }
    return -1;
}

int ll_destroy(linked_list_p list) {
    if (list == NULL) {
        return -1;
    }

    linked_list_node_p node_ptr = list->tail;

    for(int i = list->size-1; i > 0; i--) {
        if (node_ptr->next) {
            free(node_ptr->next);
            node_ptr->next = NULL;
        }

        node_ptr = node_ptr->previous;

        if (node_ptr->next->previous) {
            node_ptr->next->previous = NULL;
        }

        free(node_ptr->next);
        node_ptr->next = NULL;

    }

    free(list->head);
    list->head = NULL;

    list->size = 0;
    return 0;
}

int ll_get(linked_list_p list, uint32_t index, uint8_t *data){
    if (list == NULL) {
        return -1;
    }

    if (index >= list->size) {
        return -1;
    }

    linked_list_node_p node_ptr = list->head;

    for (int i = 0; i < index; i++){
        if (node_ptr == NULL) {
            return -1;
        }
        node_ptr = node_ptr->next;
    }

    *data = node_ptr->data.data;

    return 0;
}

int ll_remove(linked_list_p list, uint32_t index) {

    if (list == NULL) {
        return -1;
    }

    if (index > list->size-1) {
        return -1;
    }

    linked_list_node_p node_to_delete;

    if (index == 0) {
        node_to_delete = list->head;
        list->head = list->head->next;

        free(list->head->previous);
        list->head->previous = NULL;

        free(node_to_delete->next);
        node_to_delete->next = NULL;
        node_to_delete = NULL;
        free(node_to_delete);

        list->size --;
        return 0;
    }

    if (index == list->size-1) {
        node_to_delete = list->tail;
        list->tail = list->tail->previous;

        free(list->tail->next);
        list->tail->next = NULL;

        free(node_to_delete->previous);
        node_to_delete->previous = NULL;
        free(node_to_delete);
        node_to_delete = NULL;

        list->size --;
        return 0;
    }


    linked_list_node_p node_ptr = list->head;
    for (int i = 0; i < index-1; i++) {
        node_ptr = node_ptr->next;
    }
    node_to_delete = node_ptr->next;

    node_ptr->next->next->previous = node_ptr;
    node_ptr->next = node_ptr->next->next;

    node_to_delete->next = NULL;
    node_to_delete->previous = NULL;
    free(node_to_delete->next);
    free(node_to_delete->previous);

    list->size--;
    
    return 0;
}

这是主要的:我已经尝试自己测试它但不确定它是否是正确的方法。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linked_list.h"



static void print_data(uint8_t data){
    printf("%d", data);
}

int main(int argc, char *argv[]){
    static linked_list_t list;

    ll_create(&list, print_data);


    ll_add_first(&list, 2);
    ll_insert(&list, 13, 0);
    ll_remove(&list, 32);
    ll_add_last(&list, 3);
    ll_add_last(&list, 4);
    ll_print(&list);
    ll_destroy(&list);
    ll_print(&list);
    ll_add_last(&list, 5);
    ll_add_last(&list, 6);
    ll_add_first(&list, 7);
    ll_print(&list);
    ll_print_backward(&list);
    ll_insert(&list, 8, 4);
    printf("list size : %ld\n", list.size);
    ll_insert(&list, 8, list.size);
    ll_print(&list);

    //TODO use every API functions

    // ll_get
    uint8_t get_data = 0;
    ll_get(&list, 95, &get_data);
    printf("got data : %d\n\n", get_data);

    // ll_remove
    ll_remove(&list, 5);
    ll_print(&list);

    // ll_insert
    ll_insert(&list, 10, 2);
    ll_print(&list);
    // ll_contains
    uint8_t data_to_find = 96;
    printf("The data %d is in the list : %s", data_to_find, ll_contains(&list, data_to_find) ? "true\n" : "false\n");
    data_to_find = 10;
    printf("The data %d is in the list : %s", data_to_find, ll_contains(&list, data_to_find) ? "true\n" : "false\n");
    printf("\n");

    // ll_first_index
    data_to_find = 10;
    printf("The data %d is at node [%d]\n", data_to_find, ll_first_index(&list, data_to_find));
    data_to_find = 96;
    printf("The data %d is at node [%d]\n", data_to_find, ll_first_index(&list, data_to_find));


    // ll_indexes
    ll_add_last(&list, 25);
    ll_add_first(&list, 25);
    ll_insert(&list, 25, list.size);

    ll_print(&list);
    uint32_t *indexes = NULL;
    uint32_t indexes_size = 0;

    if (ll_indexes(&list, 25, &indexes, &indexes_size) == 0) {
        for (int i = 0; i < indexes_size; i++) {
            printf("%d ", indexes[i]);
        }
        printf("\n");
    }
    free(indexes);

    if (ll_indexes(&list, 6, &indexes, &indexes_size) == 0) {
        for (int i = 0; i < indexes_size; i++) {
            printf("%d ", indexes[i]);
        }
        printf("\n");
    }
    free(indexes);

    if (ll_indexes(&list, 7, &indexes, &indexes_size) == 0) {
        for (int i = 0; i < indexes_size; i++) {
            printf("%d ", indexes[i]);
        }
        printf("\n");
    }

    free(indexes);

    ll_destroy(&list);

    ll_destroy(&list);

    return 0;
}

我对这些东西很陌生,并试图将 if 条件放在我可以测试的错误上,但是我对测试这个 API 的想法已经用完了,也许我忽略了一些事情?

c memory-leaks dynamic-memory-allocation doubly-linked-list
1个回答
0
投票

在提高 API 质量之前,您首先需要检查代码并移除错误。

例如,即使是您提供的代码中的第一个函数

ll_create
也没有意义,而且会产生内存泄漏

int ll_create(linked_list_p list, void (*print_data)(uint8_t)) {
    if (list == NULL) {
        list = calloc(1, sizeof(linked_list_p));
        return 0;
    }
    return -1;
}

因为退出函数后分配的内存地址丢失了

对于这个函数的调用

ll_create(&list, print_data);

函数返回

-1
.

函数的第二个参数也没有使用。

或另一个例子。目前还不清楚为什么函数

ll_destroy
在main的最后被调用了两次。

ll_destroy(&list);

ll_destroy(&list);

这会导致未定义的行为,因为函数中的尾部未设置为 NULL。

© www.soinside.com 2019 - 2024. All rights reserved.