下面的程式,目的是遍歷一條鍊錶,逐條的刪除沒乙個節點。
[code]
struct list_head *listp;
struct arethe* arethep;
list_for_each(listp, arethe_list)
[/code]
但是,在執行時,會出現記憶體引用出錯的問題. 在分析list_del與list_for_each後,發現在list_del之後,list_for_each以無法再遍歷剩下的鍊錶。因為listp->next與listp->prev與鍊錶都以沒有關聯。此時,採用list_for_each_safe(pos,n,head)巨集可解決問題。該巨集與前者的區別主要是採用了另外乙個指標n來儲存pos的下乙個節點的位置,因此在刪除某個節點以後,儲存了剩下的節點的資訊。相應**應修改為如下:
[code]
struct list_head *listp;
struct list_head *listn;
struct arethe* arethep;
list_for_each_safe(listp, listn, arethe_list)
arethep = list_entry(listp, struct arethe, list_entry);
printk("arethe_list->arethe_ip: %d/n", arethep->arethe_ip);
[/code]
有一點需要注意的是,無論是list_for_each還是list_for_each_safe,都遍歷不到頭結點.
[code]
#include
#include
#include
module_license("gpl");
module_author("arethe");
struct arethe;
int arethe_ip = 0;
struct list_head *arethe_list;
int list_head_init(void)
list_for_each(listp, arethe_list)
arethep = list_entry(listp, struct arethe, list_entry);
printk(kern_alert"arethe->arethe_ip: %d/n", arethep->arethe_ip);
return 0;
}void list_head_exit(void)
arethep = list_entry(listp, struct arethe, list_entry);
printk("arethe_list->arethe_ip: %d/n", arethep->arethe_ip);
}module_init(list_head_init);
module_exit(list_head_exit);
[/code]
執行結果為:
[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: arethep->ip: 10
del: arethep->ip: 9
del: arethep->ip: 8
del: arethep->ip: 7
del: arethep->ip: 6
del: arethep->ip: 5
del: arethep->ip: 4
del: arethep->ip: 3
del: arethep->ip: 2
arethe_list->arethe_ip: 1
[/code]
雙向迴圈鍊錶的刪除
刪除某個結點,其實就是插入某個結點的逆操作。還是對於雙向迴圈鍊錶,要在連續的三個結點s,p,q中刪除p結點,只需把s的右鏈域指標指向q,q的左鏈域指標指向s,並收回p結點就完成了。下面就是乙個應用雙向迴圈鍊錶刪除演算法的例子 include include include define n 10 t...
雙向鍊錶的插入刪除運算
include include define len sizeof struct node typedef int datatype typedef struct node dlinklist dlinklist head 雙向鍊錶的前插運算 在結點p之前 dlinklist dinsert bef...
雙向鍊錶的查詢與刪除
雙向鍊錶的查詢工作 解析 使用next指標遍歷,直到找到資料為data的節點,如果找到節點,返回節點,否則返回null 查詢節點,成功則返回滿足條件的節點指標,否則返回null dbnode findnode dbnode head,int data dbnode pnode head if hea...