2013-10-02 1 views
1

필자가 작성하지 않은 코드에서 몇 가지 이상한 Coverity 버그를 추적하고 있습니다. 한 경우, 우리는 TAILQ_FIRST 및 TAILQ_REMOVE은과 같이, 루프에서 사용TAILQ_REMOVE가 헤드 포인터를 재설정하지 않는 이유는 무엇입니까?

while (!TAILQ_EMPTY(&queue)) 
{ 
    item* entry = TAILQ_FIRST(&queue); 
    TAILQ_REMOVE(&queue, entry, next); 
    free(entry); 
} 

커버 리티 내가 두 번 해방이야 말, 이것에 대해 많이 뿌려줍니다. 나는 헤드 노드를 삭제하면 다른 관련 매크로 달리

#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) 

, 나는 tqe_first을 재설정 여기에 아무것도 표시되지 않습니다 (내 리눅스 박스에 /usr/include/x86_64-linux-gnu/sys/queue.h) : 그러나, TAILQ_REMOVE보고이 바로 수 있습니다. 따라서, 나는 내 루프에서 삭제 된 노드를 계속 얻을 것이다.

하지만 실제로 어떤 일이 일어나는지 이해하지 못합니다. 이 코드는 Coverity 경고에도 불구하고 작동하는 것으로 보입니다.

그물을 찾는 것은 어렵습니다.

+0

가명에서 제공하는 경고를 추가하는 것이 도움이 될 수 있습니다 – nos

답변

2

tqe_prev은 포인터를 가리키는 포인터이기 때문에 작동합니다. 공백이 아닌 경우 큐의 첫 번째 요소는 tqe_first의 주소로 초기화 된 tqe_prev 필드를가집니다. 따라서 매크로의 마지막 줄 에서처럼 역 참조 해제 및 할당을 수행하면 첫 번째 요소를 제거하는 경우 tqh_first이 설정됩니다. (일반적으로 tqe_prev의 주소는 이전 노드의 tqe_next 포인터의 주소입니다.)

관련 문제