我使用优先级队列创建程序,我需要在程序结束时释放所有内存。我使用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);
}
答案 0 :(得分:2)
优先级队列保留您传递它的指针。这意味着队列必须承担内存的所有权。您需要从队列中提取项目的代码,以便在处理每个项目时调用free
。
我们无法看到代码,它是实际调用priq_pop
的代码。但泄漏报告似乎表明调用priq_pop
的代码不会释放返回的项目。
您解决此问题的步骤是:
realloc
替换为等效的malloc
,但读起来更好。free(link)
。这是不正确的,因为队列拥有内存。free()
并完成处理退回的项目时,都会向priq_pop
添加来电。答案 1 :(得分:0)
您最终应该释放队列中推送的所有链接。