具有唯一列表id的链表的C实现
我需要在内核代码中实现一个链表,不确定它是否太重要。代码应该用0到255之间的数字标识每个链表。每个节点在列表和一些其他数据字段中也有一个id。我有一些麻烦,使它的工作,不知道是什么出了问题,我写得很清楚,但它似乎有分割的问题。我很高兴了解这里出了什么问题 注意:我很确定问题不在于它使用的是内核函数具有唯一列表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>
#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关键字只意味着变量仅在翻译单元中可用,并不意味着您需要将标题存储在列表中。标准的做法是,链表包含指向头部甚至尾部的指针。您的列表数组应该根据您尝试执行的操作来保存指向列表的指针,或者保存数组中的列表本身,因为它们大多只保存指向其头部的指针。