簡體   English   中英

C valgrind發生內存泄漏

[英]C Memory leak with valgrind

我正在嘗試在一個開源項目中使用C中的鏈接列表來實現Queue。 我已經實現了Queue,編寫了單元測試,並使用valgrind解決了大部分內存泄漏。

現在的問題是,我已經嘗試了幾個小時來查找最后8個字節的泄漏,但似乎無法弄清楚。

這是valgrind的輸出:

==25806== 8 bytes in 1 blocks are definitely lost in loss record 1 of 1
==25806==    at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==25806==    by 0x80484E3: node_create (in /home/karysto/c-datastructures/queue/tests.out)
==25806==    by 0x8048511: enqueue (in /home/karysto/c-datastructures/queue/tests.out)
==25806==    by 0x8048851: test_dequeue_updates_size (in /home/karysto/c-datastructures/queue/tests.out)
==25806==    by 0x8048978: test_suite (in /home/karysto/c-datastructures/queue/tests.out)
==25806==    by 0x80489B0: main (in /home/karysto/c-datastructures/queue/tests.out)
==25806== 
==25806== LEAK SUMMARY:
==25806==    definitely lost: 8 bytes in 1 blocks
==25806==    indirectly lost: 0 bytes in 0 blocks
==25806==      possibly lost: 0 bytes in 0 blocks
==25806==    still reachable: 0 bytes in 0 blocks
==25806==         suppressed: 0 bytes in 0 blocks
==25806== 

這是隊列鏈接列表的結構:

struct Queue {
    int size;
    struct Node *front;
    struct Node *back;
};

struct Node {
    int data;
    struct Node *next;
};

這是queue.cdequeue的實現。

void
dequeue(struct Queue *q) {

    /* Dequeue from an empty queue. */
    if (q->size == 0) {
        return;
    }

    /* Dequeue the only node. */
    else if (q->size == 1) {
        q->front = NULL;
        q->back  = NULL;
        free(q->front);
        free(q->back);
    }

    /* Regular case. */
    else if (q->size > 1) {
        struct Node *temp;
        temp = q->front;
        q->front = q->front->next;
        free(temp);
    }

    --(q->size);
    return;
}

這是同一個文件中的enqueue

void
enqueue(struct Queue *q, int data) {
    struct Node *head = node_create(data);

    /* First enqueue on empty. */
    if (q->front == NULL && q->back == NULL) {
        q->front = head;
        q->back  = head;
    }

    else {
        q->back->next = head;
        q->back       = head;
    }

    ++(q->size);
    return;
}

為了完整起見, node_create是從enqueue引用的node_create函數:

struct Node*
node_create(int d) {
    struct Node *n = malloc(sizeof(struct Node));
    n->data = d;
    n->next = NULL;
    return n;
}

我認為您的問題出在最后一個節點的出隊上:

/* Dequeue the only node. */
else if (q->size == 1) {
    q->front = NULL;
    q->back  = NULL;
    free(q->front);
    free(q->back);
}

您有效地調用了兩次free(NULL) 允許使用free(NULL) ,但不執行任何操作。 因此,您最終將無法釋放節點並丟失內存。 您應該分配NULL釋放后的正面和背面,你也應該free的最后一個節點只有一次:

/* Dequeue the only node. */
else if (q->size == 1) {
    free(q->front);
    q->front = NULL;
    q->back  = NULL;
}

(這里,前后是相同的。出隊時,您最多也要刪除一個節點,因此您最多只能釋放一個節點。)

怎么樣:

/* Dequeue the only node. */
    else if (q->size == 1) {
        free(q->front);
        q->front = NULL;
        q->back  = NULL;
    }

說明:在原始解決方案中,您首先要在free()之前將q->frontq->back指向NULL NULL 運行free() 不會破壞Universe,但是它並不能做很多事情,即不對您的最后一個節點進行free()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM