簡體   English   中英

正確的釋放記憶的方法

[英]Right way to free memory

我使用優先級隊列創建程序,我需要在程序結束時釋放所有內存。 我使用Valgrind來查找內存泄漏,我在此代碼中收到警告:

int len;

//vlozeni prvniho prvku
len = snprintf(NULL, 0, "%d,%d", startX, startY);
char *link = malloc(len + 1);
sprintf(link,"%d,%d", startX, startY);
priq_push(queue, link, 0);

while(1)
{
    for(some_condition)
    {
        if(another_condition)
        {
            len = snprintf(NULL, 0, "%d,%d", neighbourX, neighbourY);
            link = realloc(NULL, len + 1);
            sprintf(link,"%d,%d", neighbourX, neighbourY);
            priq_push(queue, link, elementHeight + heights[neighbourX][neighbourY]);
            break;
        }
    }

    if(f == 1)
    {
        break;
    }
}

free(link);

使用此代碼,我從Valgrind得到這個警告:

4 bytes in 1 blocks are definitely lost in loss record 1 of 4
==9069==    at 0x4C2C857: malloc (vg_replace_malloc.c:291)
==9069==    by 0x401233: main (main.c:229)
==9069== 
==9069== 7,628,843 bytes in 932,764 blocks are definitely lost in loss record 4 of 4
==9069==    at 0x4C2C857: malloc (vg_replace_malloc.c:291)
==9069==    by 0x4C2C9CB: realloc (vg_replace_malloc.c:687)
==9069==    by 0x401554: main (main.c:305)

第291行是第一個malloc: char *link = malloc(len + 1);

我做錯了什么?

編輯。

void priq_push(priority_queue q, void *data, int height)
{
    q_elem_t *b;
    int n, m;

    if (q->position >= q->alloc) 
    {
        q->alloc *= 2;
        b = q->buffer = realloc(q->buffer, sizeof(q_elem_t) * q->alloc);
    } 
    else
    {
        b = q->buffer;
    }

    n = q->position++;
    /* append at end, then up heap */
    while ((m = n / 2) && height < b[m].height)
    {
        b[n] = b[m];
        n = m;
    }
    b[n].data = data;
    b[n].height = height;
}

/* remove top item. returns 0 if empty. *priority can be null. */
void * priq_pop(priority_queue q, int *height)
{
    void *out;
    if (q->position == 1)
    {
        return 0;
    }

    q_elem_t *b = q->buffer;

    out = b[1].data;
    if (height)
    {
        *height = b[1].height;
    }

    /* pull last item to top, then down heap. */
    --q->position;

    int n = 1, m;
    while ((m = n * 2) < q->position) 
    {
        if (m + 1 < q->position && b[m].height > b[m + 1].height)
        {
            m++;
        }

        if (b[q->position].height <= b[m].height)
        {
            break;
        }
        b[n] = b[m];
        n = m;
    }

    b[n] = b[q->position];
    if (q->position < q->alloc / 2 && q->position >= 16)
    q->buffer = realloc(q->buffer, (q->alloc /= 2) * sizeof(b[0]));

    return out;
}

我自己編寫函數,最后會釋放隊列

void free_queue(priority_queue queue)
{
    free(queue->buffer);
    free(queue);
}

優先級隊列保留您傳遞它的指針。 這意味着隊列必須承擔內存的所有權。 您需要從隊列中提取項目的代碼,以便在處理每個項目時free調用。

我們看不到代碼,它是實際調用priq_pop的代碼。 但泄漏報告似乎表明調用priq_pop的代碼沒有釋放返回的項目。

您解決此問題的步驟是:

  1. malloc替換realloc ,它是等效的,但讀起來更好。
  2. 移除推環末端的free(link) 這是不正確的,因為隊列擁有內存。
  3. 無論何時調用priq_pop並完成處理返回的項目,都要調用free()

您最終應該釋放隊列中推送的所有鏈接。

暫無
暫無

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

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