具有唯一列表id的链表的C实现

具有唯一列表id的链表的C实现,c,data-structures,linked-list,implementation,C,Data Structures,Linked List,Implementation,我需要在内核代码中实现一个链表,不确定它是否太重要。代码应该用0到255之间的数字标识每个链表。每个节点在列表和一些其他数据字段中也有一个id。我有一些麻烦,使它的工作,不知道是什么出了问题,我写得很清楚,但它似乎有分割的问题。我很高兴了解这里出了什么问题 注意:我很确定问题不在于它使用的是内核函数 #undef __KERNEL__ #define __KERNEL__ #undef MODULE #define MODULE #include <linux/kernel.h>

我需要在内核代码中实现一个链表,不确定它是否太重要。代码应该用0到255之间的数字标识每个链表。每个节点在列表和一些其他数据字段中也有一个id。我有一些麻烦,使它的工作,不知道是什么出了问题,我写得很清楚,但它似乎有分割的问题。我很高兴了解这里出了什么问题

注意:我很确定问题不在于它使用的是内核函数

#undef __KERNEL__
#define __KERNEL__
#undef MODULE
#define MODULE
#include <linux/kernel.h>  
#include <linux/module.h>  
#include <linux/fs.h>       
#include <linux/uaccess.h>  
#include <linux/string.h>   

MODULE_LICENSE("GPL");

typedef struct Node { 
    long node_id;
    char data[256];
    int data_size;
    struct Node next;
};

typedef struct List { 
    int list_id;
    struct Node head;
};

/* array holds the Lists by their list_id number */
static struct List* lists = (List*) kmalloc(256 * sizeof(List), GFP_KERNEL);

static struct List* get_list(int list_id) {
    return lists[list_id];
}

static struct Node* get_node(struct List* list, long node_id) {
    struct Node* node = list->head;
    while (node != NULL) {
        if (node->node_id == node_id) {
            return node;
        }
        node = node->next;
    }
    return NULL;
}

static void add_node(struct List* list, long node_id) {
    struct Node* node;
    node = kmalloc(sizeof(Node), GFP_KERNEL);
    node->next = list->head;
    list->head = node;
}

static void add_list(int list_id) {
    struct List* list;
    list = kmalloc(sizeof(List), GFP_KERNEL);
    list->list_id = list_id;
    lists[list->list_id] = list;
}

static void free_list(struct List* list) {
    if (list == NULL) {
        return;
    }
    while (list->head != NULL) {
        struct Node* node = list->head;
        list->head = node->next;
        kfree(node);
    }
    kfree(list);
}

static void free_lists(void) {
    int list_id;
    for (list_id = 0 ; list_id < 256; list_id++) {
        free_list(lists[list_id]);
    }
}
结构节点下一步

结构节点定义中的这一行特别创建非终止递归,其中结构节点需要另一个已定义的结构节点才能正确定义,这需要另一个结构节点,依此类推:

我们使用指针是因为我们可以用NULL终止链表,这意味着没有更多的节点可以连接,除此之外:

我假设您试图以这种方式实现链接列表和节点,就像它们是函数中的指针一样,最值得注意的是get_list

另一件值得一提的事情是:

kmalloc是为内核中小于页面大小的对象分配内存的正常方法

,我不知道您使用的是什么Linux版本或环境。在做出以下假设后,您可能需要重新考虑这些数据结构的总体实现,或者至少重新考虑kmalloc的使用:

Linux使用的默认页面大小为4kb 节点结构使用8字节指针、4字节整数、1字节字符和8字节长整数,占用276字节。 添加另一个整数的列表结构占用280字节。 静态结构列表*列表分配的大小是列表结构的256倍,最大可达72kb,远远超过页面大小。
首先,我建议您创建一个列表,使用指向head节点的指针,而不是让列表存储head本身。我还建议您使用最大容量为256的字符数据[256]a,这样也可以节省一些空间。我还建议您使用指向列表的指针数组static struct List*List[256],而不是static struct List*List或static struct List List[256]。

在struct Node成员元素中,假设是指向下一个节点的指针。我不确定它是否是有效的定义,您可能不应该使用kmalloc来分配列表。由于它的大小是固定的,所以可以使用静态分配的数组:static struct List[256];。您的typedef struct语句没有提供标记,因此它们是多余的-因此只需声明结构而不使用typedef即可。内核在list.h中已经有一个链表实现。这个不适合你使用吗?@kaylum这感觉像是一个本科生的操作系统/内核模块家庭作业:谢谢,这很有道理。有一件事我仍然不确定,那就是我应该如何实现榜首?因为它是静态的,所以我需要256个头。将列表仅设为头节点指针是否合理?静态结构节点*头[256],仅实现节点结构?否则?@Aladin static关键字只意味着变量仅在翻译单元中可用,并不意味着您需要将标题存储在列表中。标准的做法是,链表包含指向头部甚至尾部的指针。您的列表数组应该根据您尝试执行的操作来保存指向列表的指针,或者保存数组中的列表本身,因为它们大多只保存指向其头部的指针。