C ++ libevent использование (утечка памяти и оператор удаления) - PullRequest
1 голос
/ 06 мая 2011

У меня есть два файла:

// 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)

Ответы [ 3 ]

2 голосов
/ 06 мая 2011

При использовании delete компилятор должен видеть тип объекта, на который указывает объект, чтобы определить, есть ли какие-либо деструкторы, которые он должен вызвать в этой точке.

С другой стороны, valgrind, похоже, говорит, что память выделяется с помощью malloc и calloc. В этом случае вам вообще не следует использовать delete, но, возможно, free.

Во втором случае, при использовании free, valgrind по-прежнему жалуется на утечки памяти. Одна из возможностей здесь состоит в том, что объект события содержит указатели на другие выделения, которые также должны быть освобождены.

В этом случае должна быть другая функция event_free или event_release, которую вы должны вызвать, чтобы вернуть объект события. У вас есть один из них?

1 голос
/ 06 мая 2011

Первый вопрос: delete должен знать тип указателя, который он удаляет, поскольку может потребоваться вызвать деструктор.

Секунд Вопрос: см. Комментарий ниже вопроса. Нам нужно знать, что делает event_init и как он распределяет память, чтобы сообщить о существующих утечках памяти. Тем не менее, хороший совет: доверяйте Valgrind.

0 голосов
/ 15 ноября 2012

Libevent не написан на C ++ и, следовательно, не использует деструкторы.Никогда не следует использовать delete для кода, который не был выделен с помощью new.

Если вы прочитали руководство libevent в разделе "освобождение базы событий" , в нем говорится, что вы должны использовать:

void event_base_free(struct event_base *base);

Также event_new функция для выделения базы событий устарела (поскольку она не является поточно-ориентированной), вместо нее следует использовать:

struct event_base *event_base_new(void);
...