[英]C Memory leak with valgrind
I'm trying to implement a Queue using a linked list in C, in an open-source project. 我正在尝试在一个开源项目中使用C中的链接列表来实现Queue。 I'm at the point where I've implemented the Queue, wrote unit tests, and worked out most of the memory leaks using valgrind.
我已经实现了Queue,编写了单元测试,并使用valgrind解决了大部分内存泄漏。
The problem now is that I've been trying to find the leak for these last 8 bytes for a couple hours now, and I can't seem to figure it out. 现在的问题是,我已经尝试了几个小时来查找最后8个字节的泄漏,但似乎无法弄清楚。
Here is the output from valgrind: 这是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==
Here's my structs for the queue linked list: 这是队列链接列表的结构:
struct Queue {
int size;
struct Node *front;
struct Node *back;
};
struct Node {
int data;
struct Node *next;
};
Here's queue.c
, the implementation for dequeue
. 这是
queue.c
, dequeue
的实现。
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;
}
And here's the enqueue
in the same file. 这是同一个文件中的
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;
}
For completness, here's the node_create
function that is being referenced from enqueue
: 为了完整起见,
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;
}
I think that your problem lies in dequeuing the last node: 我认为您的问题出在最后一个节点的出队上:
/* Dequeue the only node. */
else if (q->size == 1) {
q->front = NULL;
q->back = NULL;
free(q->front);
free(q->back);
}
You effectively call free(NULL)
twice. 您有效地调用了两次
free(NULL)
。 free(NULL)
is allowed, but it doesn't do anything. 允许使用
free(NULL)
,但不执行任何操作。 So you end up not freeing the node and lose the memory. 因此,您最终将无法释放节点并丢失内存。 You should assign
NULL
to the front and back after freeing and you should also free
the last node only once: 您应该分配
NULL
释放后的正面和背面,你也应该free
的最后一个节点只有一次:
/* Dequeue the only node. */
else if (q->size == 1) {
free(q->front);
q->front = NULL;
q->back = NULL;
}
(Here, the front and back are the same. You are also remobving at most one node when dequeuing, so you should only free at most one node.) (这里,前后是相同的。出队时,您最多也要删除一个节点,因此您最多只能释放一个节点。)
How about: 怎么样:
/* Dequeue the only node. */
else if (q->size == 1) {
free(q->front);
q->front = NULL;
q->back = NULL;
}
Explanation: In your original solution you were first pointing both q->front
and q->back
to NULL
before free()
ing them. 说明:在原始解决方案中,您首先要在
free()
之前将q->front
和q->back
指向NULL
。 Running free()
on NULL
doesn't destroy the universe but it doesn't do very much, ie not free()
ing your last node. 在
NULL
上运行free()
不会破坏Universe,但是它并不能做很多事情,即不对您的最后一个节点进行free()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.