总是内存泄漏,即使我释放了所有分配

Always a memory leak even though I free'd all allocates

我似乎找不到 prio_q_create 函数为什么总是泄漏的问题。我用 prio_q_destroy 释放了它,但 valgrind 仍然显示泄漏错误。

#include <stdlib.h>
#include <stdio.h>

typedef struct prio_q prio_q;
typedef struct elem elem;
struct prio_q {
    int size;           
    struct elem *first; 
};

struct elem {
    void *data;
    int prio;
    struct elem *next;
};

struct prio_q *prio_q_create() {
    prio_q *list = calloc(1, sizeof(prio_q));
    list->first = NULL;
    list->size = 0;
    return list;
}

void prio_q_push(struct prio_q *q, void *data, int prio) {
    elem *e = calloc(1, sizeof(elem));
    e->prio = prio;
    e->data = data;
    e->next = NULL;
    if (q->first == NULL) {
        q->first = e;
        q->size = q->size + 1;
    } else {
        if (q->first->prio < prio) {
            e->next = q->first;
            q->first = e;
            q->size = q->size + 1;
        } else {
            elem *temp = q->first;
            while (temp->next != NULL && temp->next->prio >= prio) {
                temp = temp->next;
            }
            e->next = temp->next;
            temp->next = e;
            q->size = q->size + 1;
        }
    }
}

void *prio_q_pop(struct prio_q *q) {
    if (q->first != NULL) {
        elem *temp = q->first;
        q->first = q->first->next;
        void *data = temp->data;
        temp->next = NULL;
        free(temp);
        return data;
    } else
        exit(0);
}

void *prio_q_front(struct prio_q *q) {
    return q->first->data;
}

void prio_q_destroy(struct prio_q *q) {
    elem *temp = q->first;                 
    elem *next_temp;                           
    while (temp != NULL) {        
        next_temp = temp->next;
        free(temp);
        temp = next_temp;        
    } 
    free(q);
}

int main() {
    struct prio_q *queue;
    char *s;
    int i;

    queue = prio_q_create();

    prio_q_push(queue, "amet...", 2);
    prio_q_push(queue, "ipsum", 7);
    prio_q_push(queue, "dolor", 4);
    prio_q_push(queue, "Lorem", 22);
    prio_q_push(queue, "sit", 3);

    prio_q_push(queue, "Hello World", 1);
    prio_q_push(queue, "Bye World", 0);

    for (i = 0; i < 5; i++) {
        s = prio_q_pop(queue);
        printf("%s\n", s);
    }

    s = prio_q_front(queue);
    printf("%s\n", s);
    prio_q_destroy(queue);
    return 0;
}

应该是完整的代码。 main 主要是将一些带有 prio 编号的字符串推送到列表中,并通过循环将它们打印出来。

发布的代码没有泄漏。您正在测试未发布的代码,或者您的 Valgrind 版本可能检测到由 C 库为 stdout 分配缓冲区引起的误报。尝试不使用 printf 语句。

这是我的 Valgrind 跟踪:

chqrlie$ make memleak
gcc -O2 -funsigned-char -std=c99 -Wall -Wextra -W -Wmissing-field-initializers -lm -o memleak memleak.c
chqrlie$ valgrind ./memleak
==45671== Memcheck, a memory error detector
==45671== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==45671== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==45671== Command: ./memleak
==45671==
amet...
ipsum
dolor
Lorem
sit
Hello World
==45671==
==45671== HEAP SUMMARY:
==45671==     in use at exit: 0 bytes in 0 blocks
==45671==   total heap usage: 8 allocs, 8 frees, 184 bytes allocated
==45671==
==45671== All heap blocks were freed -- no leaks are possible
==45671==
==45671== For counts of detected and suppressed errors, rerun with: -v
==45671== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
chqrlie$