我有两个文件:
// 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)
答案 0 :(得分:2)
使用delete
时,编译器需要查看指向的对象的类型,以确定是否需要在该点调用任何析构函数。
另一方面,valgrind似乎说使用malloc和calloc分配内存。在这种情况下,您根本不应使用delete
,但可能free
。
在第二种情况下,当使用free
时,valgrind仍会抱怨内存泄漏。这里的一种可能性是事件对象包含指向其他需要释放的分配的指针。
在这种情况下,应该调用另一个函数event_free
或event_release
来返回事件对象。你有其中一个吗?
答案 1 :(得分:1)
第一个问题:删除需要知道它删除的指针的类型,因为它可能需要调用析构函数。
秒问题:请参阅问题下方的评论。我们需要知道event_init做了什么以及如何将内存分配给有关现有内存泄漏的建议。但是,一个很好的建议:信任Valgrind。
答案 2 :(得分:0)
Libevent不是用C ++编写的,因此它不使用析构函数。您永远不应对未使用delete
分配的代码使用new
。
如果您阅读manual下的libevent "deallocating an event base",则说明您应该使用:
void event_base_free(struct event_base *base);
用于分配事件库的event_new
函数也是deprecated(因为它不是线程安全的),你应该使用:
struct event_base *event_base_new(void);