为什么会泄漏内存?
我有一个函数,当调用时,它从 struct Torrent 中获取 struct Pieces* 字段,并根据 char 数组中包含的信息对其进行初始化。
函数调用如下所示 (metadata.c:230):
get_pieces(t.pieces, &t.num_pieces, data);
在 get_pieces()
函数中,我初始化 t.pieces
,如下所示 (metadata.c: 65):
pieces = calloc(*num_pieces, sizeof(struct Piece));
然而,当我运行 valgrind 时,它说:
==8701== 76,776 bytes in 1 blocks are definitely lost in loss record 634 of 634
==8701== at 0x4C28349: calloc (vg_replace_malloc.c:467)
==8701== by 0x4025A4: get_pieces (metadata.c:65)
==8701== by 0x402CDB: init_torrent (metadata.c:230)
==8701== by 0x404018: start_torrent (torrent.c:35)
==8701== by 0x40232E: main (main.c:17)
即使当我的程序终止并且可以释放指针时,t->pieces
仍然可用。为什么会泄漏内存?
完整的源代码可在 https://github.com/robertseaton/slug 获取。
I have a function that, when called, takes a struct Pieces*
field from a struct Torrent
and initializes it according to the information contained in a char array.
Here is what the function call looks like (metadata.c:230):
get_pieces(t.pieces, &t.num_pieces, data);
In the get_pieces()
function, I initialize t.pieces
, like so (metadata.c:65):
pieces = calloc(*num_pieces, sizeof(struct Piece));
However, when I run valgrind, it says:
==8701== 76,776 bytes in 1 blocks are definitely lost in loss record 634 of 634
==8701== at 0x4C28349: calloc (vg_replace_malloc.c:467)
==8701== by 0x4025A4: get_pieces (metadata.c:65)
==8701== by 0x402CDB: init_torrent (metadata.c:230)
==8701== by 0x404018: start_torrent (torrent.c:35)
==8701== by 0x40232E: main (main.c:17)
even though a pointer, t->pieces
, is still available when my program terminates and can be free'd. Why does this leak memory?
The full source code is available at https://github.com/robertseaton/slug.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
函数完成后,调用者
作为第一个参数传递的对象没有改变,因此malloc的结果丢失了。因此我不知道如何释放
碎片
。编辑
正如用户 user786653 在评论中观察到的那样,您需要更改您的功能:
You have
After the function is done, the object passed by the caller as the first argument is unchanged, so the result of
malloc
is lost. Therefore I don't see how you can freepieces
.EDIT
As user user786653 observes in the comments, you need to change your function:
这会泄漏内存,因为您的
get_pieces
函数正在传递一个指向 Pieces 的指针:然后您可以在此方法内向
pieces
分配内存。当它返回时,分配的内存将不再能被任何东西访问。这是因为您的指针是按值传递的 - 重新分配指针不会更改调用函数的副本。为了影响该调用函数,您必须将指针传递给指针,以便您可以正确分配原始副本:
并且,在调用站点,将地址传递给指针。
This leaks memory because your
get_pieces
function is passing in a pointer to Pieces:You then allocate memory to
pieces
inside of this method. When it returns, that allocated memory is no longer accessible by anything.This is because your pointer is passed by value - reassigning the pointer does not change the calling function's copy. In order to affect that calling function, you'd have to pass a pointer to the pointer, so you can assign the original copy correctly:
And, at the call site, pass in the address to the pointer.
在调用中,
您按值传递指针 t.pieces,因此它会被复制以在函数中使用。由于您在函数内部而不是外部对其进行赋值,并且现在它们是两个不同的指针,因此外部指针永远不会被赋值。函数内部的指针通过堆栈展开被销毁,分配的内存位于堆上,被遗忘。
您可以通过将调用更改为来解决此问题
In the call
you are passing the pointer t.pieces by value, so it is copied for use in the function. Since you assign to it inside the function but not outside, and these are now two different pointers, the outer pointer is never assigned. The pointer inside the function is destroyed via stack unwinding and the allocated memory sits there on the heap, forgotten.
You can fix this by changing the call to