1

私は2つのファイルを持っています:

// 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:関数内'int main()':
event_test_delete.cpp:8:9:警告:削除演算子の呼び出しで検出された問題の可能性:
event_test_delete.cpp:5:14:警告:「ev」のタイプが不完全です
/usr/include/event.h:211:8:警告:「structevent_base」の前方宣言
event_test_delete.cpp:8:9:注:クラスの定義時に宣言されている場合でも、デストラクタもクラス固有の演算子deleteも呼び出されません。

しかし、g++ event_test_free.cpp -levent -o event_test_free.oevent_test_free.cppをコンパイルすると、同じエラーが発生しないのはなぜですか?

そして2番目の質問は(valgrindを使用して)なぜメモリリークがあるのか​​ということです。

最初のファイルのValgrind出力:(なぜここにあるのMismatched free() / delete / delete []ですか?)

azat:〜/ Desktop / event_test $ valgrind --show-reachable = yes --leak-check = full ./event_test_delete.o
== 4135 == Memcheck、メモリエラー検出器
== 4135 == Copyright(C)2002-2010、and GNU GPL'd、by Julian Sewardetal。
== 4135==Valgrind-3.6.0.SVNの使用-DebianとLibVEX; 著作権情報については、-hを指定して再実行してください
== 4135 ==コマンド:./ event_test_delete.o
== 4135 ==
== 4135 ==不一致free()/削除/削除[]
== 4135 == at 0x4023881:演算子delete(void *)(vg_replace_malloc.c:387)
== 4135 == by 0x8048571:main(/home/azat/Desktop/event_test/event_test_delete.o内)
== 4135 ==アドレス0x4323028は、割り当てられたサイズ944のブロック内の0バイトです
== 4135 == 0x402328F:calloc(vg_replace_malloc.c:467)
== 4135 == by 0x4047DA7:event_base_new(/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x4047EF6:event_init(/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x8048561:main(/home/azat/Desktop/event_test/event_test_delete.o内)
== 4135 ==
== 4135 ==
== 4135 ==ヒープの概要:
== 4135 ==終了時に使用中:5ブロックで672バイト
== 4135 ==合計ヒープ使用量:6つの割り当て、1つの解放、1,616バイトの割り当て
== 4135 ==
== 4135==1ブロックの8バイトが損失レコード1/5で間接的に失われます
== 4135 == 0x4023F50:malloc(vg_replace_malloc.c:236)
== 4135 == by 0x4047C7D:event_base_priority_init(/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x4047E8B:event_base_new(/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x4047EF6:event_init(/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x8048561:main(/home/azat/Desktop/event_test/event_test_delete.o内)
== 4135 ==
== 4135 == 1ブロックの12(4直接、8間接)バイトは、損失レコード2of5で確実に失われます
== 4135 == 0x402328F:calloc(vg_replace_malloc.c:467)
== 4135 == by 0x4047C2D:event_base_priority_init(/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x4047E8B:event_base_new(/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x4047EF6:event_init(/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x8048561:main(/home/azat/Desktop/event_test/event_test_delete.o内)
== 4135 ==
== 4135==1ブロックの256バイトが損失レコード3/5で間接的に失われます
== 4135 == 0x402328F:calloc(vg_replace_malloc.c:467)
== 4135 == by 0x4056192:??? (/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x4047E46:event_base_new(/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x4047EF6:event_init(/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x8048561:main(/home/azat/Desktop/event_test/event_test_delete.o内)
== 4135 ==
== 4135==1ブロックの384バイトが損失レコード4/5で間接的に失われます
== 4135 == 0x4023F50:malloc(vg_replace_malloc.c:236)
== 4135 == by 0x405616C:??? (/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x4047E46:event_base_new(/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x4047EF6:event_init(/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x8048561:main(/home/azat/Desktop/event_test/event_test_delete.o内)
== 4135 ==
== 4135 == 1ブロックの660(直接20、間接640)バイトは、損失レコード5/5で確実に失われます。
== 4135 == 0x402328F:calloc(vg_replace_malloc.c:467)
== 4135 == by 0x4056157:??? (/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x4047E46:event_base_new(/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x4047EF6:event_init(/usr/lib/libevent-1.4.so.2.1.3内)
== 4135 == by 0x8048561:main(/home/azat/Desktop/event_test/event_test_delete.o内)
== 4135 ==
== 4135 ==リークの概要:
== 4135 ==間違いなく失われました:2ブロックで24バイト
== 4135 ==間接的に失われました:3ブロックで648バイト
== 4135 ==失われる可能性があります:0ブロックで0バイト
== 4135 ==まだ到達可能:0ブロックで0バイト
== 4135 ==抑制:0ブロックで0バイト
== 4135 ==
== 4135 ==検出および抑制されたエラーのカウントについては、-vを指定して再実行します。
== 4135 ==エラーの概要:3つのコンテキストからの3つのエラー(抑制:7から28)

そして2番目のファイル

azat:〜/ Desktop / event_test $ valgrind --show-reachable = yes --leak-check = full ./event_test_free.o
== 4140 == Memcheck、メモリエラー検出器
== 4140 == Copyright(C)2002-2010、and GNU GPL'd、by Julian Sewardetal。
== 4140==Valgrind-3.6.0.SVNの使用-DebianとLibVEX; 著作権情報については、-hを指定して再実行してください
== 4140 ==コマンド:./ event_test_free.o
== 4140 ==
== 4140 ==
== 4140 ==ヒープの概要:
== 4140 ==終了時に使用中:5ブロックで672バイト
== 4140 ==合計ヒープ使用量:6つの割り当て、1つの解放、1,616バイトの割り当て
== 4140 ==
== 4140==1ブロックの8バイトが損失レコード1/5で間接的に失われます
== 4140 == 0x4023F50:malloc(vg_replace_malloc.c:236)
== 4140 == by 0x4047C7D:event_base_priority_init(/usr/lib/libevent-1.4.so.2.1.3内)
== 4140 == by 0x4047E8B:event_base_new(/usr/lib/libevent-1.4.so.2.1.3内)
== 4140 == by 0x4047EF6:event_init(/usr/lib/libevent-1.4.so.2.1.3内)
== 4140 == by 0x8048531:main(/home/azat/Desktop/event_test/event_test_free.o内)
== 4140 ==
== 4140 == 1ブロックの12(4直接、8間接)バイトは、損失レコード2of5で確実に失われます
== 4140 == 0x402328F:calloc(vg_replace_malloc.c:467)
== 4140 == by 0x4047C2D:event_base_priority_init(/usr/lib/libevent-1.4.so.2.1.3内)
== 4140 == by 0x4047E8B:event_base_new(/usr/lib/libevent-1.4.so.2.1.3内)
== 4140 == by 0x4047EF6:event_init(/usr/lib/libevent-1.4.so.2.1.3内)
== 4140 == by 0x8048531:main(/home/azat/Desktop/event_test/event_test_free.o内)
== 4140 ==
== 4140==1ブロックの256バイトが損失レコード3/5で間接的に失われます
== 4140 == 0x402328F:calloc(vg_replace_malloc.c:467)
== 4140 == by 0x4056192:??? (/usr/lib/libevent-1.4.so.2.1.3内)
== 4140 == by 0x4047E46:event_base_new(/usr/lib/libevent-1.4.so.2.1.3内)
== 4140 == by 0x4047EF6:event_init(/usr/lib/libevent-1.4.so.2.1.3内)
== 4140 == by 0x8048531:main(/home/azat/Desktop/event_test/event_test_free.o内)
== 4140 ==
== 4140==1ブロックの384バイトが損失レコード4/5で間接的に失われます
== 4140 == 0x4023F50:malloc(vg_replace_malloc.c:236)
== 4140 == by 0x405616C:??? (/usr/lib/libevent-1.4.so.2.1.3内)
== 4140 == by 0x4047E46:event_base_new(/usr/lib/libevent-1.4.so.2.1.3内)
== 4140 == by 0x4047EF6:event_init(/usr/lib/libevent-1.4.so.2.1.3内)
== 4140 == by 0x8048531:main(/home/azat/Desktop/event_test/event_test_free.o内)
== 4140 ==
== 4140 == 1ブロックの660(直接20、間接640)バイトは、損失レコード5/5で確実に失われます。
== 4140 == 0x402328F:calloc(vg_replace_malloc.c:467)
== 4140 == by 0x4056157:??? (/usr/lib/libevent-1.4.so.2.1.3内)
== 4140 == by 0x4047E46:event_base_new(/usr/lib/libevent-1.4.so.2.1.3内)
== 4140 == by 0x4047EF6:event_init(/usr/lib/libevent-1.4.so.2.1.3内)
== 4140 == by 0x8048531:main(/home/azat/Desktop/event_test/event_test_free.o内)
== 4140 ==
== 4140 ==リークの概要:
== 4140 ==間違いなく失われました:2ブロックで24バイト
== 4140 ==間接的に失われました:3ブロックで648バイト
== 4140 ==失われる可能性があります:0ブロックで0バイト
== 4140 ==まだ到達可能:0ブロックで0バイト
== 4140 ==抑制:0ブロックで0バイト
== 4140 ==
== 4140 ==検出および抑制されたエラーのカウントについては、-vを指定して再実行します。
== 4140 ==エラーの概要:2つのコンテキストからの2つのエラー(抑制:7から28)
4

3 に答える 3

2

コンパイラを使用deleteする場合、指定されたオブジェクトのタイプを確認して、その時点で呼び出す必要のあるデストラクタがあるかどうかを判断する必要があります。

一方、valgrindは、メモリはmallocとcallocを使用して割り当てられていると言っているようです。その場合は、まったく使用deleteしないでください。ただし、おそらくfree

2番目のケースでは、を使用する場合freeでも、valgrindはメモリリークについて文句を言います。ここでの1つの可能性は、イベントオブジェクトに、解放する必要のある他の割り当てへのポインタが含まれていることです。

その場合、イベントオブジェクトを返すために、別の関数が存在するevent_freeか、呼び出す必要があります。event_releaseそれらの1つがありますか?

于 2011-05-06T09:34:54.770 に答える
1

最初の質問:デストラクタを呼び出す必要がある場合があるため、deleteは削除するポインタのタイプを知る必要があります。

秒の質問:質問の下のコメントを参照してください。event_initが何をするのか、そしてそれがどのようにメモリを割り当てて既存のメモリリークについてアドバイスするのかを知る必要があります。ただし、良いアドバイス:Valgrindを信頼してください。

于 2011-05-06T09:26:15.923 に答える
0

LibeventはC++で記述されていないため、デストラクタを使用しません。deleteを使用して割り当てられていないコードでは絶対に使用しないでくださいnew

「イベントベースの割り当て解除」のlibeventマニュアルを読むと、次のように使用する必要があると記載されています。

void event_base_free(struct event_base *base);

また、event_newイベントベースを割り当てるための関数は非推奨になりました(スレッドセーフではないため)。代わりに次を使用する必要があります。

struct event_base *event_base_new(void);
于 2012-11-15T13:24:38.080 に答える