Linux内核中链表的使用

发表于:2012-8-08 09:40

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:rosetta    来源:51Testing软件测试网采编

分享:

  所以以上例子可改成如下,这样就比较简洁了。

struct ipstore *store;
    list_for_each_entry(store, &addr_list, list)
    {
      if(store->addr[0] == ist->addr[0])
      {
          if(ist)
              kfree(ist);
     
          return 0;
      }
    }

  再来看安全删除遍历接口:

#define list_for_each_entry_safe(pos, n, head, member)          \
    for (pos = list_entry((head)->next, typeof(*pos), member),  \
        n = list_entry(pos->member.next, typeof(*pos), member); \
         &pos->member != (head);                    \
         pos = n, n = list_entry(n->member.next, typeof(*n), member))

  同样把上面的例子进行修改,这样删除时就不会破坏原有链表的结构出现“使用在释放后”的程序崩溃问题:

struct ipstore *v, *n;
    list_for_each_entry_safe(v, n, &addr_list, list)
    {
        if(iph->saddr == v->addr[0])
        {
              list_del(&v->list);//删除节点
              kfree(v);//还需要注意的是list_del()只是把节点从链表中摘除,它并不释放其占用的内存,所以需要手动释放内存。
        }
    }

  5、判空操作

  判空操作也比较重要,如果为空咱就什么都不操作,直接返回

if(list_empty(&addr_list))
    {
        return 0;
    }

  总结:到此为止对于内核链表的操作基本上可以满足日常需求了,当然内核还提供移动和合并链表操作、反向遍历链表操作的接口,具体可参考LKD3e.

  对链表的操作中一不小心就会出现“使用在释放后”的程序崩溃问题,请看如下使用普通遍历并删除的代码:

DEFINE_RWLOCK(v4_rwlock);
    struct list_head *p;
    struct ipstore *store;
    list_for_each(p, &addr_list)
    {
        store = list_entry(p, struct ipstore, list);
        if(iph->saddr == store->addr[0])
        {
            read_lock(&v4_rwlock);
            list_del(&store->list);
            read_unlock(&v4_rwlock);

            kfree(store);

            return 0;
        }
    }

  这段代码虽然用了普通非安全遍历删除操作,但不会引起程序崩溃,但它已经埋下了安全隐患,不会崩溃是因为在删除链表并释放内存后直接return 0了,没再对目前的链表进行遍历移动操作,所以不会出现问题,万一哪天没return呢?。所以很多时间程序出现莫名崩溃问题都发现不了,我想这也许是个例子。

  在操作写数据时的好习惯是加一把锁,前面例子为了突出链表操作没把加解锁的代码贴出,这个例子中就有体现,首先定义了一把读写锁,在删除链表结点时加锁,删除完毕解锁。

33/3<123
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号