[英]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
的代碼沒有釋放返回的項目。
您解決此問題的步驟是:
malloc
替換realloc
,它是等效的,但讀起來更好。 free(link)
。 這是不正確的,因為隊列擁有內存。 priq_pop
並完成處理返回的項目,都要調用free()
。 您最終應該釋放隊列中推送的所有鏈接。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.