如何将链表的头部分配给 Linux 内核中的指针?
How can I assign the head of a linked list to a pointer in Linux kernel?
我正在为Linux内核编写一个程序来实现一个链表并添加一些人的出生日期。添加它们后,我需要找到最大年龄并删除该节点。
为了找到年龄最大的节点,我打算设置一个指向链表第一个元素的指针,并在遍历它时比较年龄。我不知道如何将最大指针设置为链表的头部。
我尝试了几种不同的方法,包括:
struct birthday * max = &birthday_list
struct birthday max = birthday_list
max = birthday_list.next;
我得到的错误:error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
我想我可能会将列表分配给不同的结构。我可以澄清一下我可能做错了什么吗?
#include<linux/list.h>
#include<linux/init.h>
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/types.h>
#include<linux/slab.h>
struct birthday {
int day;
int month;
int year;
struct list_head list;
}
static LIST_HEAD(birthday_list);
static void remove_oldest_student(void){
struct birthday *max, *curr, *next;
//point max to list head
max = LIST_HEAD(birthday_list);
list_for_each_entry(curr, &birthday_list, list){
//find_max(&max, &curr);
}
printk(KERN_INFO "Oldest Student Details --> Name: %s, Month: %d, Day: %d, Year: %d\n",max->name, max->month,max->day,max->year);
}
int simple_init(void) {
struct birthday *ptr;
int i;
for(i = 0; i < 5; i++) {
// create 5 birthday structs and add them to the list
struct birthday *person;
person = kmalloc(sizeof(*person), GFP_KERNEL);
person->day = 22;
person->month = 11;
person->year = 1981;
INIT_LIST_HEAD(&person->list);
list_add_tail(&person->list, &birthday_list);
}
list_for_each_entry(ptr, &birthday_list, list) {
// print the info from the structs to the log
printk(KERN_INFO "%d, %d %d", ptr->month, ptr->day, ptr->year);
}
remove_oldest_student();
return 0;
}
void simple_exit(void) {
struct birthday *ptr, *next;
list_for_each_entry_safe(ptr, next, &birthday_list, list) {
// delete structs and return memory
list_del(&ptr->list);
kfree(ptr);
}
}
module_init(simple_init);
module_exit(simple_exit);
我看到了几个问题,我确信这不是唯一的编译错误(例如 max->name
- 数据结构中没有这样的成员)。我也不想深究逻辑错误,因为这与原问题无关,是典型的作业。
进入正题。
似乎您正在尝试从另一个包含在其中(其成员)的结构对象获取指向结构的指针。它可能是这样的:
max = container_of(birthday_list.next, struct birthday, list);
阅读更多:
关于 container_of
: SO post, guide, Linux kernel source.
关于list_head
,图片不错。
UPD:正如 Tsyvarev 在他的回答中提到的,有一个 list
-API 函数 list_first_entry()
, which eventually invokes container_of()
。因此,如果您仍然 确实需要 第一个条目 - 最好使用 API 函数。 container_of()
只是为了更好地了解正在发生的事情。
I intend to set a pointer to the first element of the linked list
只需使用list_first_entry
宏:
max = list_first_entry(&birthday_list, struct birthday, list);
提示:因为你已经有了一个指向第一个元素的指针,所以没有必要在下面的循环中迭代它。您可以使用 list_for_each_entry_continue
:
而不是 list_for_each_entry
// Make iterator to point to the already located element (first element in the list)
curr = max;
// Continue iteration.
// So the first iterated element will be the second element in the list
list_for_each_entry_continue(curr, &birthday_list, list){
//find_max(&max, &curr);
}
我正在为Linux内核编写一个程序来实现一个链表并添加一些人的出生日期。添加它们后,我需要找到最大年龄并删除该节点。
为了找到年龄最大的节点,我打算设置一个指向链表第一个元素的指针,并在遍历它时比较年龄。我不知道如何将最大指针设置为链表的头部。
我尝试了几种不同的方法,包括:
struct birthday * max = &birthday_list
struct birthday max = birthday_list
max = birthday_list.next;
我得到的错误:error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
我想我可能会将列表分配给不同的结构。我可以澄清一下我可能做错了什么吗?
#include<linux/list.h>
#include<linux/init.h>
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/types.h>
#include<linux/slab.h>
struct birthday {
int day;
int month;
int year;
struct list_head list;
}
static LIST_HEAD(birthday_list);
static void remove_oldest_student(void){
struct birthday *max, *curr, *next;
//point max to list head
max = LIST_HEAD(birthday_list);
list_for_each_entry(curr, &birthday_list, list){
//find_max(&max, &curr);
}
printk(KERN_INFO "Oldest Student Details --> Name: %s, Month: %d, Day: %d, Year: %d\n",max->name, max->month,max->day,max->year);
}
int simple_init(void) {
struct birthday *ptr;
int i;
for(i = 0; i < 5; i++) {
// create 5 birthday structs and add them to the list
struct birthday *person;
person = kmalloc(sizeof(*person), GFP_KERNEL);
person->day = 22;
person->month = 11;
person->year = 1981;
INIT_LIST_HEAD(&person->list);
list_add_tail(&person->list, &birthday_list);
}
list_for_each_entry(ptr, &birthday_list, list) {
// print the info from the structs to the log
printk(KERN_INFO "%d, %d %d", ptr->month, ptr->day, ptr->year);
}
remove_oldest_student();
return 0;
}
void simple_exit(void) {
struct birthday *ptr, *next;
list_for_each_entry_safe(ptr, next, &birthday_list, list) {
// delete structs and return memory
list_del(&ptr->list);
kfree(ptr);
}
}
module_init(simple_init);
module_exit(simple_exit);
我看到了几个问题,我确信这不是唯一的编译错误(例如 max->name
- 数据结构中没有这样的成员)。我也不想深究逻辑错误,因为这与原问题无关,是典型的作业。
进入正题。
似乎您正在尝试从另一个包含在其中(其成员)的结构对象获取指向结构的指针。它可能是这样的:
max = container_of(birthday_list.next, struct birthday, list);
阅读更多:
关于 container_of
: SO post, guide, Linux kernel source.
关于list_head
,图片不错。
UPD:正如 Tsyvarev 在他的回答中提到的,有一个 list
-API 函数 list_first_entry()
, which eventually invokes container_of()
。因此,如果您仍然 确实需要 第一个条目 - 最好使用 API 函数。 container_of()
只是为了更好地了解正在发生的事情。
I intend to set a pointer to the first element of the linked list
只需使用list_first_entry
宏:
max = list_first_entry(&birthday_list, struct birthday, list);
提示:因为你已经有了一个指向第一个元素的指针,所以没有必要在下面的循环中迭代它。您可以使用 list_for_each_entry_continue
:
list_for_each_entry
// Make iterator to point to the already located element (first element in the list)
curr = max;
// Continue iteration.
// So the first iterated element will be the second element in the list
list_for_each_entry_continue(curr, &birthday_list, list){
//find_max(&max, &curr);
}