简体   繁体   English

TAILQ_REMOVE为什么不重置头指针?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM