C++ libevent的使用(内存泄漏和删除运算符)
我有两个文件:
// event_test_delete.cpp
#include <event.h>
int main() {
event_base* ev;
ev = event_init();
delete ev;
return 0;
}
当
// event_test_free.cpp
#include <event.h>
#include <cstdlib>
int main() {
event_base* ev;
ev = event_init();
free(ev);
return 0;
}
我编译 (g++ event_test_delete.cpp -levent -o event_test_delete.o
) event_test_delete.cpp 时,出现错误:
event_test_delete.cpp: In function ‘int main()’: event_test_delete.cpp:8:9: warning: possible problem detected in invocation of delete operator: event_test_delete.cpp:5:14: warning: ‘ev’ has incomplete type /usr/include/event.h:211:8: warning: forward declaration of ‘struct event_base’ event_test_delete.cpp:8:9: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
但是当我编译 g++ event_test_free.cpp -levent -o event_test_free.o
event_test_free.cpp 我没有收到相同的错误,为什么?
第二个问题是(使用valgrind)为什么会出现内存泄漏?
第一个文件的 Valgrind 输出:(为什么这里有一个 Mismatched free()/delete/delete[]
?)
azat:~/Desktop/event_test$ valgrind --show-reachable=yes --leak-check=full ./event_test_delete.o ==4135== Memcheck, a memory error detector ==4135== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al. ==4135== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info ==4135== Command: ./event_test_delete.o ==4135== ==4135== Mismatched free() / delete / delete [] ==4135== at 0x4023881: operator delete(void*) (vg_replace_malloc.c:387) ==4135== by 0x8048571: main (in /home/azat/Desktop/event_test/event_test_delete.o) ==4135== Address 0x4323028 is 0 bytes inside a block of size 944 alloc'd ==4135== at 0x402328F: calloc (vg_replace_malloc.c:467) ==4135== by 0x4047DA7: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x8048561: main (in /home/azat/Desktop/event_test/event_test_delete.o) ==4135== ==4135== ==4135== HEAP SUMMARY: ==4135== in use at exit: 672 bytes in 5 blocks ==4135== total heap usage: 6 allocs, 1 frees, 1,616 bytes allocated ==4135== ==4135== 8 bytes in 1 blocks are indirectly lost in loss record 1 of 5 ==4135== at 0x4023F50: malloc (vg_replace_malloc.c:236) ==4135== by 0x4047C7D: event_base_priority_init (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x4047E8B: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x8048561: main (in /home/azat/Desktop/event_test/event_test_delete.o) ==4135== ==4135== 12 (4 direct, 8 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 5 ==4135== at 0x402328F: calloc (vg_replace_malloc.c:467) ==4135== by 0x4047C2D: event_base_priority_init (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x4047E8B: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x8048561: main (in /home/azat/Desktop/event_test/event_test_delete.o) ==4135== ==4135== 256 bytes in 1 blocks are indirectly lost in loss record 3 of 5 ==4135== at 0x402328F: calloc (vg_replace_malloc.c:467) ==4135== by 0x4056192: ??? (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x4047E46: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x8048561: main (in /home/azat/Desktop/event_test/event_test_delete.o) ==4135== ==4135== 384 bytes in 1 blocks are indirectly lost in loss record 4 of 5 ==4135== at 0x4023F50: malloc (vg_replace_malloc.c:236) ==4135== by 0x405616C: ??? (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x4047E46: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x8048561: main (in /home/azat/Desktop/event_test/event_test_delete.o) ==4135== ==4135== 660 (20 direct, 640 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 5 ==4135== at 0x402328F: calloc (vg_replace_malloc.c:467) ==4135== by 0x4056157: ??? (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x4047E46: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3) ==4135== by 0x8048561: main (in /home/azat/Desktop/event_test/event_test_delete.o) ==4135== ==4135== LEAK SUMMARY: ==4135== definitely lost: 24 bytes in 2 blocks ==4135== indirectly lost: 648 bytes in 3 blocks ==4135== possibly lost: 0 bytes in 0 blocks ==4135== still reachable: 0 bytes in 0 blocks ==4135== suppressed: 0 bytes in 0 blocks ==4135== ==4135== For counts of detected and suppressed errors, rerun with: -v ==4135== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 28 from 7)
对于第二个文件
azat:~/Desktop/event_test$ valgrind --show-reachable=yes --leak-check=full ./event_test_free.o ==4140== Memcheck, a memory error detector ==4140== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al. ==4140== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info ==4140== Command: ./event_test_free.o ==4140== ==4140== ==4140== HEAP SUMMARY: ==4140== in use at exit: 672 bytes in 5 blocks ==4140== total heap usage: 6 allocs, 1 frees, 1,616 bytes allocated ==4140== ==4140== 8 bytes in 1 blocks are indirectly lost in loss record 1 of 5 ==4140== at 0x4023F50: malloc (vg_replace_malloc.c:236) ==4140== by 0x4047C7D: event_base_priority_init (in /usr/lib/libevent-1.4.so.2.1.3) ==4140== by 0x4047E8B: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3) ==4140== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3) ==4140== by 0x8048531: main (in /home/azat/Desktop/event_test/event_test_free.o) ==4140== ==4140== 12 (4 direct, 8 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 5 ==4140== at 0x402328F: calloc (vg_replace_malloc.c:467) ==4140== by 0x4047C2D: event_base_priority_init (in /usr/lib/libevent-1.4.so.2.1.3) ==4140== by 0x4047E8B: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3) ==4140== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3) ==4140== by 0x8048531: main (in /home/azat/Desktop/event_test/event_test_free.o) ==4140== ==4140== 256 bytes in 1 blocks are indirectly lost in loss record 3 of 5 ==4140== at 0x402328F: calloc (vg_replace_malloc.c:467) ==4140== by 0x4056192: ??? (in /usr/lib/libevent-1.4.so.2.1.3) ==4140== by 0x4047E46: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3) ==4140== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3) ==4140== by 0x8048531: main (in /home/azat/Desktop/event_test/event_test_free.o) ==4140== ==4140== 384 bytes in 1 blocks are indirectly lost in loss record 4 of 5 ==4140== at 0x4023F50: malloc (vg_replace_malloc.c:236) ==4140== by 0x405616C: ??? (in /usr/lib/libevent-1.4.so.2.1.3) ==4140== by 0x4047E46: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3) ==4140== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3) ==4140== by 0x8048531: main (in /home/azat/Desktop/event_test/event_test_free.o) ==4140== ==4140== 660 (20 direct, 640 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 5 ==4140== at 0x402328F: calloc (vg_replace_malloc.c:467) ==4140== by 0x4056157: ??? (in /usr/lib/libevent-1.4.so.2.1.3) ==4140== by 0x4047E46: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3) ==4140== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3) ==4140== by 0x8048531: main (in /home/azat/Desktop/event_test/event_test_free.o) ==4140== ==4140== LEAK SUMMARY: ==4140== definitely lost: 24 bytes in 2 blocks ==4140== indirectly lost: 648 bytes in 3 blocks ==4140== possibly lost: 0 bytes in 0 blocks ==4140== still reachable: 0 bytes in 0 blocks ==4140== suppressed: 0 bytes in 0 blocks ==4140== ==4140== For counts of detected and suppressed errors, rerun with: -v ==4140== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 28 from 7)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当使用
delete
时,编译器需要查看指向的对象的类型,以确定此时是否需要调用任何析构函数。另一方面,valgrind似乎说内存是使用malloc和calloc分配的。在这种情况下,您根本不应该使用
delete
,而应该使用free
。在第二种情况下,当使用
free
时,valgrind仍然抱怨内存泄漏。这里的一种可能性是事件对象包含指向也需要释放的其他分配的指针。在这种情况下,应该调用另一个函数
event_free
或event_release
来返回事件对象。你有其中之一吗?When using
delete
the compiler needs to see the type of the object pointed to, to determine if there are any destructors it needs to call at that point.On the other hand, valgrind seems to say that the memory is allocated using malloc and calloc. In that case, you should not use
delete
at all, but perhapsfree
.In the second case, when using
free
, valgrind still complains on memory leaks. One possibility here is that the event object contains pointers to other allocations that also need to be freed.In that case, there should be another function
event_free
orevent_release
you should call, to return the event object. Do you have one of those?第一个问题:delete 需要知道它删除的指针的类型,因为它可能需要调用析构函数。
秒问题:请参阅问题下面的评论。我们需要知道 event_init 的作用以及它如何分配内存以提供有关现有内存泄漏的建议。然而,一个好的建议是:相信 Valgrind。
First Question: delete needs to know the type of the pointer it deletes, since it might need to call a destructor.
Seconds Question: see the comment below the question. We need to know what event_init does and how it allocates the memory to advice about existing memory leaks. However, a good advice: Trust Valgrind.
Libevent 不是用 C++ 编写的,因此它不使用析构函数。您永远不应该对尚未使用
new
分配的代码使用delete
。如果您阅读 手册 .wangafu.net/~nickm/libevent-book/Ref2_eventbase.html#_deallocating_an_event_base" rel="nofollow">"解除分配事件库" 它指出您应该使用:
还有
event_new
分配事件库的函数已弃用 (因为它不是线程安全的),你应该使用:Libevent is not written in C++, and hence it does not use destructors. You should never use
delete
on code that hasn't been allocated usingnew
.If you read the libevent manual under "deallocating an event base" it states that you should use:
Also the
event_new
function for allocating an event base is deprecated (since it's not thread safe), you should instead use: