The following program traverses a linked list and deletes no node one by one.
[Code]
Struct list_head * listp;
Struct arethe * aretrip;
List_for_each (listp, arethe_list)
{
Arethe= list_entry (listp, struct arethe, list_entry );
List_del (listp );
Kfree (aretrip );
}
[/Code]
However, memory reference errors may occur during execution. After analyzing list_del and list_for_each, it is found that after list_del, list_for_each cannot traverse the remaining linked list. Because listp-> next and listp-> Prev are not associated with the linked list. In this case, the list_for_each_safe (Pos, N, head) macro can be used to solve the problem. The difference between the macro and the former is that another pointer N is used to store the position of the next node of the POs. Therefore, after deleting a node, the information of the remaining nodes is saved. The corresponding code should be modified as follows:
[Code]
Struct list_head * listp;
Struct list_head * listn;
Struct arethe * aretrip;
List_for_each_safe (listp, listn, arethe_list)
{
Arethe= list_entry (listp, struct arethe, list_entry );
List_del (listp );
Kfree (aretrip );
}
Arethe= list_entry (listp, struct arethe, list_entry );
Printk ("arethe_list-> arethe_ip: % d/N", aretrip-> arethe_ip );
[/Code]
One thing to note is that neither list_for_each nor list_for_each_safe can traverse the header node.
The following is an example of list_head:
[Code]
# Include <Linux/module. h>
# Include <Linux/kernel. h>
# Include <arethe_dbg.h>
Module_license ("GPL ");
Module_author ("arethe ");
Struct arethe {
Struct list_head list_entry;
Int arethe_ip;
};
Int arethe_ip = 0;
Struct list_head * arethe_list;
Int list_head_init (void)
{
Struct list_head * listp;
Struct arethe * aretrip;
Int arethe_num = 10;
Int I = 0;
For (I = 0; I <arethe_num; I ++)
{
Aretrip = kzarloc (sizeof (* arethohhot), gfp_kernel );
Arethe_ip ++;
Arethe_ip = arethe_ip;
Printk (kern_alert "arethe_ip: % d/N", arethe_ip );
Init_list_head (& aretrip-> list_entry );
If (! Arethe_list)
Arethe_list = & aretrip-> list_entry;
Else
List_add (aretrip, arethe_list );
}
List_for_each (listp, arethe_list)
{
Arethe= list_entry (listp, struct arethe, list_entry );
Printk (kern_alert "arethe-> arethe_ip: % d/N", arethohhot-> arethe_ip );
}
Arethe= list_entry (listp, struct arethe, list_entry );
Printk (kern_alert "arethe-> arethe_ip: % d/N", arethohhot-> arethe_ip );
Return 0;
}
Void list_head_exit (void)
{
Struct list_head * listp;
Struct list_head * listn;
Struct arethe * aretrip;
List_for_each_safe (listp, listn, arethe_list)
{
Arethe= list_entry (listp, struct arethe, list_entry );
Printk (kern_alert "DEL: arethohhot-> IP: % d/N", arethohhot-> arethe_ip );
// If (listp-> next! = Listp & listp-> Prev! = Listp)
List_del (listp );
Kfree (aretrip );
}
Arethe= list_entry (listp, struct arethe, list_entry );
Printk ("arethe_list-> arethe_ip: % d/N", aretrip-> arethe_ip );
}
Module_init (list_head_init );
Module_exit (list_head_exit );
[/Code]
The running result is:
[Code]
Arethe_ip: 1
Arethe_ip: 2
Arethe_ip: 3
Arethe_ip: 4
Arethe_ip: 5
Arethe_ip: 6
Arethe_ip: 7
Arethe_ip: 8
Arethe_ip: 9
Arethe_ip: 10
Arethe-> arethe_ip: 10
Arethe-> arethe_ip: 9
Arethe-> arethe_ip: 8
Arethe-> arethe_ip: 7
Arethe-> arethe_ip: 6
Arethe-> arethe_ip: 5
Arethe-> arethe_ip: 4
Arethe-> arethe_ip: 3
Arethe-> arethe_ip: 2
Arethe-> arethe_ip: 1
DEL: aretrip-> IP: 10
DEL: aretrip-> IP: 9
DEL: aretrip-> IP: 8
DEL: aretrip-> IP: 7
DEL: aretrip-> IP: 6
DEL: aretrip-> IP: 5
DEL: aretrip-> IP: 4
DEL: aretrip-> IP: 3
DEL: aretrip-> IP: 2
Arethe_list-> arethe_ip: 1
[/Code]