2012-02-09 18 views
11

Çekirdek bağlantılı liste API'sini nasıl kullanacağımı öğreniyorum list.h.Çekirdek bağlantılı listedeki düğümleri silmek için neden list_for_each_safe() dosyasına ihtiyacımız var?

list_for_each() kullanmak yerine list_del() ile düğümleri silerken list_for_each_safe() kullanmam gerektiğini öğrendim. list_for_each_safe() için

Kodu: list_for_each() için

#define list_for_each_safe(pos, n, head) \ 
    for (pos = (head)->next, n = pos->next; pos != (head); \ 
     pos = n, n = pos->next) 

Kodu:

for (pos = (head)->next; pos != (head); pos = pos->next) 

İkisinin de çok _safe sürümü fazladan argüman alır dışında benzer 'geçici depolama' olarak kullanılacak fark (burada belirtilmiştir, list.h).

Silme işlevi için normalde, silme işlemi için düzgün, _safe sürümünü ne zaman uygulayacağımı anlıyorum, ancak ek argümanın 'güvenli' olmasını nasıl sağladığını merak ediyorum.

struct kool_list{ 
    int to; 
    struct list_head list; 
    int from; 
    }; 

struct kool_list *tmp; 
struct list_head *pos, *q; 
struct kool_list mylist; 

list_for_each_safe(pos, q, &mylist.list){ 
     tmp= list_entry(pos, struct kool_list, list); 
     printf("freeing item to= %d from= %d\n", tmp->to, tmp->from); 
     list_del(pos); 
     free(tmp); 
    } 

Nasıl silme içinde q yardım veren vermez: Ben list_for_each_safe() kullanarak bağlı bir listedeki her düğümü siliyorum nerede

aşağıdakileri düşünün?

Yardımlarınız için teşekkürler!

+0

o yalındır bu hiç düşünmemiştim ben hallederim, Teşekkürler ! –

+0

q daha iyi bir şekilde adlandırılmış olmalı .. pos_next gibi bir şey. –

cevap

20

pos alanları. Örneğinizde döngü gövdesi, pos tarafından işgal edilen belleği bile serbest bırakır. döngü güvenli olmayan bir sürümünü kullanmak olduğunu varsayalım: pos = pos->next:

for (pos = (head)->next; pos != (head); pos = pos->next) 

pos işaretçi arttırma ifadesinin kırma geçersiz hale gelir döngü gövdesi çalıştırıldıktan sonra.

olarak zıt, güvenli foreach yerine pos çözümleyecek ikincisi atıfta sonra geçici bir değişkene pos->next değerini önceden kaydeder ve:

for (pos = (head)->next, n = pos->next; pos != (head); \ 
    pos = n, n = pos->next) 
2
pos = start; 
del(pos); 
pos = pos->next; 

pos = start; 
n = pos->next; 
del(pos); 
pos = n; 

del() ücretsiz ise

() ve memset'in() karşıt olarak, ihtimalini iyice> sonraki tanımsız list_del içten değerini değiştirir çünkü gereklidir

İlgili konular