C++ libevent usage (memory leak and delete operator)
I have two files:
// event_test_delete.cpp
#include <event.h>
int main() {
event_base* ev;
ev = event_init();
delete ev;
return 0;
}
And
// event_test_free.cpp
#include <event.h>
#include <cstdlib>
int main() {
event_base* ev;
ev = event_init();
free(ev);
return 0;
}
When I compile (g++ event_test_delete.cpp -levent -o event_test_delete.o
) event_test_delete.cpp I get an error:
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.
But when I compile g++ event_test_free.cpp -levent -o event_test_free.o
event_test_free.cpp I don`t get the same error why?
And the second question is (using valgrind) why there is a memory leak?
Valgrind output for first file: (why here is an 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 0x开发者_JS百科4056157: ??? (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)
And for second file
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)
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 perhaps free
.
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
or event_release
you should call, to return the event object. Do you have one of those?
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 is not written in C++, and hence it does not use destructors. You should never use delete
on code that hasn't been allocated using new
.
If you read the libevent manual under "deallocating an event base" it states that you should use:
void event_base_free(struct event_base *base);
Also the event_new
function for allocating an event base is deprecated (since it's not thread safe), you should instead use:
struct event_base *event_base_new(void);
精彩评论