[C] 双向循环链表宏实现的坑

来源:互联网 发布:最新域名地址 编辑:程序博客网 时间:2024/05/21 07:07

这几天在写一个基于Rateless编码的单向加速工具,
因为之前在Linux内核中看过这种宏实现的双向循环链表,
所以也就没有细细研究,直接套用了KCP中的宏定义,
然后就埋坑了。

#define IQUEUE_DEL(entry) (\    (entry)->next->prev = (entry)->prev, \    (entry)->prev->next = (entry)->next, \    (entry)->next = 0, (entry)->prev = 0)

触发bug的场景:

// qhead是一个额外的链表头部,当时队列中除此之外仅有一个元素,iqueue_del(qhead.next);

上述代码展开后:

    (qhead.next)->next->prev = (qhead.next)->prev, \    (qhead.next)->prev->next = (qhead.next)->next, \    (qhead.next)->next = 0, (qhead.next)->prev = 0)
    (qhead.next)->next->prev = (qhead.next)->prev, \    (qhead.next)->prev->next = (qhead.next)->next, \    // 其实,一直到这里,都是正常运行的;    (qhead.next)->next = 0, (qhead.next)->prev = 0)    // 但是这里,由于前面的修改,qhead.next已经不再指向队列中的头个元素,    // 而是指向自身;实质上就等效于qhead->next = 0, (qhead.next)->prev = 0;    // 访问NULL指针,直接crash

Fix:

tmp = qhead.next;iqueue_del(tmp);
阅读全文
0 0
原创粉丝点击