C语言中的双自由或损坏释放队列

icomxhvb  于 2023-06-21  发布在  其他
关注(0)|答案(1)|浏览(118)

我有一个队列(在Linux,C),它使用以下结构:

typedef struct Packet {
    char buffer[600];
    int32_t buf_length;
} Packet;

typedef struct Node {
    Packet *packet_p;
    struct Node *next;
} Node;

typedef struct Queue {
    Node *front;
    Node *rear;
    int size;
} Queue;

之后,我有典型的功能,以推动,弹出,读取的数量的元素...一切正常。但是,有时(非常非常少)我会得到以下错误:

double free or corruption (out)

经过一段时间的调试和添加打印,看看它失败的地方,我发现清除队列功能导致了这一点。
这是我的功能:

void clearQueue(Queue *queue) {

    printf("CQ1\r\n");
    while (!isEmpty(queue)) {
        Node *temp = queue->front;
        if (queue->front == NULL) {
            printf("CQX1\r\n");
            queue->rear = NULL;
        } else {
            printf("CQ2\r\n");
            if (temp->packet_p != NULL) {
                free(temp->packet_p);
            }
            printf("CQ3\r\n");
            if (temp != NULL) {
                free(temp);
            }
            printf("CQ4\r\n");
            if (queue->size > 0) {
                queue->size--;
            }
        }
    }
}

这是我在崩溃前得到的输出:

CQ1
CQ2
CQ3
CQ4
CQ2
double free or corruption (out)
Aborted

我在clear函数中有2个free,因为enqueue函数是这样创建的:

void enqueue(Queue *queue, const Packet *item) {
    Node *newNode = (Node *)malloc(sizeof(Node));

    if (newNode == NULL) {
        return;
    }
    newNode->packet_p = (Packet *)malloc(sizeof(Packet));
    if (newNode->packet_p == NULL) {
        free(newNode);
        return;
    }

    memcpy(newNode->packet_p->buffer, item->buffer, item->buf_length);
    newNode->packet_p->buf_length = item->buf_length;

    newNode->next = NULL;

    if (isEmpty(queue)) {
        queue->front = newNode;
       queue->rear = newNode;
    } else {
        queue->rear->next = newNode;
        queue->rear = newNode;
    }
    queue->size++;
}

有办法解决吗?它能以一种更好的方式重新工作吗(很确定它能,但我没有其他想法)

n8ghc7c1

n8ghc7c11#

clearQueue函数没有更新队列中的前指针。在释放当前节点之前,前端指针应前进到下一个节点。
比如这样:

void clearQueue(Queue *queue){
    Node *temp;
    while(queue->front != NULL){
        temp = queue->front;
        queue->front = queue->front->next; //Advance front to the next item
        if(temp->packet_p != NULL){
           free(temp->packet_p);
        }
        free(temp);
        if(queue->size > 0){
           queue->size--;
        }
    }
    queue->rear = NULL;
   
}

相关问题