2011-07-29 11 views
3

オプションのICUサポートを有効にしてboost regexクラスを使用すると(詳細はboost documentationを参照してください)メモリリークや、リセット/クリーンアップのようです。icuのu32_regexメモリリーク/キャッシュWin32でのブースト

誰もがこれを見て、キャッシュをクリアする方法を知っているので、ブーストユニットテストフレームワークがメモリリークを報告しないでしょうか?

私の問題の詳細は以下のとおりです。 -

ICU version 4.6.0 
(Built using supplied vs2010 solution in debug and release configuration) 
Boost version 1.45 
(built with command "bjam variant=debug,release threading=multi link=shared stage" since standard distribution does not include icu support in regex) 
OS Windows 7 
Compiler MSVC 10 (Visual Studio 2010 Premium) 

私はそうは思わない、私は同じ結果と私のシステム上に構築されていることが起こったICU 4.2.1でブースト1.42でこれを試してみましたけどそれは最新のバージョンである1.47 icu 4.8.1を上げるように変更することによって解決される問題です。

により、コマンドラインからコンパイルすることができ
#define BOOST_TEST_MAIN //Ask boost unit test framework to create a main for us 
#define BOOST_ALL_DYN_LINK //Ask boost to link to dynamic library rather than purely header support where appropriate 
#include <boost/test/auto_unit_test.hpp> 

#include <boost/regex.hpp> 
#include <boost/regex/icu.hpp> //We use icu extensions to regex to support unicode searches on utf-8 
#include <unicode/uclean.h> //We want to be able to clean up ICU cached objects 

BOOST_AUTO_TEST_CASE(standard_regex) 
{ 
    boost::regex re("\\d{3}"); 
} 

BOOST_AUTO_TEST_CASE(u32_regex) 
{ 
    boost::u32regex re(boost::make_u32regex("\\d{3}")); 
    u_cleanup(); //Ask the ICU library to clean up any cached memory 
} 

: - - :あなたのためのヘッダ/ LIBSへの適切なパスで

C:\>cl test.cpp /I[BOOST HEADERS PATH] /I[ICU HEADERS] /EHsc /MDd -link /LIBPATH:[BOOST LIB PATH] [ICU LIB PATH]icuuc.lib 

次のコード(Test.cppのを)コンパイル

machine

適切なブーストDLLが、(boost_regex-vc100-mt-gd-1_45.dllおよびboost_unit_test_framework-vc100-mt-gd-1)がパッティングされていない場合、test.exeを含むディレクトリにコピーします。 _45.dll)

実行するとTEST.EXEを上記の手順から私が得る: -

Running 2 test cases... 

*** No errors detected 
Detected memory leaks! 
Dumping objects -> 
{789} normal block at 0x00410E88, 28 bytes long. 
Data: < 0N U  > 00 00 00 00 30 4E CD 55 00 00 00 00 01 00 00 00 
{788} normal block at 0x00416350, 14 bytes long. 
Data: <icudt46l-coll > 69 63 75 64 74 34 36 6C 2D 63 6F 6C 6C 00 
{787} normal block at 0x00415A58, 5 bytes long. 
Data: <root > 72 6F 6F 74 00 
...lots of other blocks removed for clarity ... 

私はそれがの開始時に、その名前を持っているがため、ICUは、犯人がここに実際にあると推測しています2ブロック目。

最初のテスト(つまり、u32_regexではなく標準正規表現を作成する)だけでメモリリークは検出されません。

複数のu32_regexをテストに追加しても、メモリがリークすることはありません。

icu documentationに従ってu_cleanup()呼び出しを使用してicuキャッシュをクリーンアップしようとしましたが、ICUの初期化と終了のセクションを参照してください。

私はicuライブラリに精通していません(実際にはユニコード対応の正規表現サポートが必要なので実際に使用しています)、ICUが存在するときにu_cleanup()コールで実際にデータをクリーンアップする方法はわかりません。 boost regex dllによって読み込まれています。ただ、問題を改めて表明する

があるように思われる: - オプションのICUサポート(私はこれはICUへの静的リンクを使用していますが、ここで間違っている可能性がありますかなり確信している)

でコンパイルされたDLL内

ブースト正規表現

私はu_cleanup()を呼び出すことができるようにテストプログラムでicuuc.libにリンクすると、これはboost regexライブラリ経由でロードされたICUのインスタンスによって保持されているメモリに影響を与えないように見えます(そうすれば)

regexライブラリで私が実際に私たちがmaにしたい場所にあるICUデータをクリーンアップするように要求するコールは見つかりません電話をかける。

答えて

1

u_cleanupはデータをクリーンアップするものですが、アイテムがまだ開いている場合はデータをクリーンアップできません。

ブースト機能を呼び出さず、u_cleanup()を呼び出してリークがないかどうか確認できますか? u_init()を呼び出してからu_cleanup()

私は上記のコードが正規表現をクリーンアップするかどうか、またはブーストに内部キャッシュがあるかどうかを知るためにブーストに精通していません。 ICUのデータがまだ開かれていた場合、漏れたオブジェクトは通常のICUデータのようには見えませんが、14 + 5バイトではなくかなりのデータが表示されます。

+0

ありがとうございました - それは漏れたデータの始まりに過ぎませんでした。私はうまくいけばそれをより明確にする質問を編集しました。 –

+0

さらなる調査では、icuは実際には静的リンクではなくダイナミックリンクであることが示されています。 icu dllが見つからない場合、icu dllを削除してもdllが見つかりませんでした(動的または静的リンクがあるかどうかを確認する簡単なテストでした)場合は、Boost regexが正常に機能しなくなります。したがって、u_cleanup()はうまくいくはずです。 –

+1

プリプロセッサフ​​ラグUCLN_NO_AUTO_CLEANUPを0に定義してICUを構築した場合(uconfig.hの先頭に#defineを追加できます)、ICUはDLLがアンロードされると自身をクリーンアップします。 ICUがすでにクリーンアップされているか、まったくロードされていない場合、u_cleanupは安全に呼び出すことができます。 –

1

ちょうど私がこれを解決してください(ブーストユーザーの助けを借りて)。

問題は、順番に問題があります。ブースト正規表現dllの静的オブジェクトがユニットテストフレームワークの前で破壊されていない場合、これはまだいくつかのデータをキャッシュしています。 UTFはメモリリークを報告します。単にu_cleanup()を呼び出すだけでは不十分です。

順序を保証する最も簡単な方法は、ユニットテストフレームワークを静的ライブラリとしてリンクすることです。これにより、dllの後にオブジェクトが破棄され、キャッシュされたオブジェクトは既にメモリリークとして報告されません破壊された。

関連する問題