[英]Why doesn't TAILQ_REMOVE reset the head pointer?
I'm tracking down a few odd Coverity bugs in some code I didn't write. 我正在跟踪一些我未编写的代码中的一些Coverity错误。 In one case, we use TAILQ_FIRST and TAILQ_REMOVE in a loop, like so: 在一种情况下,我们在循环中使用TAILQ_FIRST和TAILQ_REMOVE,如下所示:
while (!TAILQ_EMPTY(&queue))
{
item* entry = TAILQ_FIRST(&queue);
TAILQ_REMOVE(&queue, entry, next);
free(entry);
}
Coverity complains a lot about this, saying I'm double-freeing. Coverity对此抱怨很多,说我要双重释放。 However, looking at TAILQ_REMOVE, this might be right: ( /usr/include/x86_64-linux-gnu/sys/queue.h
on my Linux box) 但是,查看TAILQ_REMOVE可能是正确的:(在我的Linux机器上为/usr/include/x86_64-linux-gnu/sys/queue.h
)
#define TAILQ_REMOVE(head, elm, field) do { \
if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
} while (/*CONSTCOND*/0)
Unlike in some other related macros, I don't see anything here that resets tqe_first
if I delete the head node. 与其他一些相关宏不同,在这里我看不到任何删除头节点会重置tqe_first
。 Thus, I would keep getting the deleted node in my loop. 因此,我将继续在循环中获取已删除的节点。
But I don't really understand what's going on. 但是我真的不明白发生了什么。 This code appears to work despite the Coverity warnings. 尽管存在Coverity警告,但此代码似乎仍然有效。
Finding examples on the net for this is difficult. 为此很难在网上找到实例。
This works because tqe_prev
is a pointer to a pointer. 这是tqe_prev
因为tqe_prev
是指向指针的指针。 If non-empty, the first element in the queue has its tqe_prev
field initialized to the address of the tqe_first
. 如果非空,在队列中的第一个元素都有tqe_prev
字段初始化为地址tqe_first
。 So, dereferencing it and assigning to it, as it does in the last line of the macro, will end up setting the tqh_first
if you are removing the first element. 因此,如果要删除第一个元素,则像在宏的最后一行中那样对它进行引用和分配,最终将设置tqh_first
。 (Normally, tqe_prev
would have the address of the tqe_next
pointer of the previous node.) (通常, tqe_prev
具有上一个节点的tqe_next
指针的地址。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.