2016-07-05 17 views
0

空のコンソールアプリケーションを作成し、その中にSTLコンテナを使用すると、アプリケーションが終了したときにFastMMがメモリリークを報告します。例えばC++ Builder 6のSTLコンテナでFastMMがメモリリークを報告します

、私はstd::vector<int>main()で作成する場合:

std::vector<int> v; 

コンパイル、実行して、近くに、何のリークが報告されていません。

私が行う場合:

std::vector<int> v; 
v.push_back(100); 

私が手:

このアプリケーションがメモリをリークしています。小ブロック漏れは、次のとおり

309から340バイト:不明X 1

同様に、私が報告漏れを得る:

std::vector<int> v; 
v.push_back(100); 
v.clear(); 

、また漏れが上に報告される:

std::vector<int> v; 
v.reserve(1); 

std::dequeのようないくつかの容器では、その内容を変更するだけで十分であり、漏れがあるアプリケーションが終了すると、

誰でも何が起こっているのか説明できますか?私はBorland C++ Builder 6とFastMM4を使用します。私はFastMMOptions.incのさまざまな設定を変更していますが、私はまだこれらのリークが報告されているのを見ています。

+3

[Borland C++ Builder 6](https://en.wikipedia.org/wiki/C%2B%2BBuilder#Version_history)は、2002年に登場したようです。現代のコンパイラ?より新しいバージョンのC++ Builder? 14年間はソフトウェア面で長い時間です。 – CoryKramer

+0

私は、コードスニペットを与えられているので、コンパイラによる誤った 'std :: vector'実装以外のメモリリーク(周囲のコンテキストを参照することなく)を引き起こすものはありません。または、漏出検出器によって報告された偽陽性。 – CoryKramer

+0

はい、私たちはボーランドXE7を持っており、新しいプロジェクトは新しい環境で開発されています。しかし、既存のプロジェクトでメモリリークを調べる必要があります。私たちはまだそのサイズのためにXE7に移行していません。 FastMMは非常に便利ですが、STLはコードの多くの場所で使用されているため、私を非常に混乱させる漏れを指摘しています。 – bboydushko

答えて

1

vectorの内部配列に使用されるメモリを解放しないstd::vectorクリア、単にアレイ内の項目を破棄した後、設定し、それが新しいに再利用できるようにアレイ自体がまだ割り当てられてstd::vector::size() 0にvectorにプッシュされたアイテム。 vectorのデストラクタは、配列の割り当てを解除します。

C++ Builder 6では、デフォルトのSTLライブラリはSTLPortです(C++ Builder 2006ではDinkumwareに置き換えられました)。 ~std::vector()のSTLPortの実装は、(clear()が呼び出されたかのように)配列項目を破棄するだけで、配列自体の割り当てを解除しないので、表示されている「リーク」です。版STLPortウェブサイト上で、次のFAQによると、実際には全くリークどちらではありません。

Q6.2 My tool detect memory leaks in application with STLport. Is this leak from STLport?

A6.2ほとんどのケースでは、この「擬似メモリリーク」誤っていくつかのツールサポートしていることです。

STLportのデフォルトコンパイルでは、ノードアロケータが内部メモリを割り当てるために使用されます。ノード・アロケータは、大きなメモリ・チャンクを事前に割り当て、小さなメモリ・ブロックを引き渡すことによって動作します。メモリーチャンクは、STLportを使用するアプリケーションの実行中に解放されません(つまり、システムに戻らない、BoundsChecker、Purify、Valgrindなどのメモリリークをチェックするツール、使用されなくなっても解放されないメモリこれらのツールは、STLportのノードアロケータを使用すると、誤ったメモリリークを報告することがあります。メモリチャンクは通常アプリケーション終了時に解放されますが、メモリチェッカは通常、その時点より前にメモリリークを報告します。 STLportを内部的に使用し、静的にリンクされている共有ライブラリ(DLL、Windows DLLモデル固有のこの問題など)を使用すると、別のメモリの問題が報告されることがあります。メモリがdllに割り当てられ、それ以外のメモリに解放された場合、STLportノードアロケータは、将来の使用のために解放されたメモリを保持します。このメモリを使用しないと、実際のメモリリークがなくてもアプリケーションのグローバルメモリ消費量はappliがクラッシュするまで増加します。これは、dllの中のすべてのものや静的なlibのすべてを一貫して使用する必要がある理由です。

擬似メモリリークを削除する方法があります(メモリがプログラムの最後に正しく解放されているため、リークは擬似メモリです)。 STLportで使用される別のアロケータを使用できます。ファイル"stlport/stl/_site_config.h"とのコメントを外しいずれか、次のいずれかの開き:

_STLP_USE_NEWALLOC enables a simple allocator that uses "new/delete" 
_STLP_USE_MALLOC  enables a simple allocator that uses "malloc/free" 

削除/新しいアロケータは、メモリの枯渇を追跡するためのエントリポイントを与えるという利点を有しているが、詳細については、お使いのコンパイラのドキュメントまたはC++標準でset_new_handlerを見ます。

また、次のシンボルを定義して、"stlport/stl/_site_config.h"でコメントを外すこともできます。

_STLP_LEAKS_PEDANTIC 

記号はすべてのメモリチャンクを強制的に解放します。また、設定ファイルのシンボルの周りのコメントも見てください。

ファイルを変更した場合は、STLportとアプリケーションとすべての依存ライブラリを再コンパイルする必要があることに注意してください。

STLportのメモリ問題のデバッグに役立ついくつかの定義もあります。 _STLP_DEBUGモードでは、単にも「./stlport/stl_user_config.h」にしたり、プロジェクト設定のいずれかで、次の記号を定義します。

_STLP_DEBUG_ALLOC 
_STLP_DEBUG_UNINITIALIZED   

あなたはこれらのオプションのためにSTLportを再構築する必要はありませんが、あなたが持っていますファイルを変更した場合は、アプリケーションとすべての依存ライブラリを再構築します。

これまでのC++ Builderバージョンで使用されていたRogueWave STLも、古いコードとの下位互換性のために出荷されており、この問題は発生しません。プロジェクトの条件リストに_USE_OLD_RW_STLを定義することで、STLPortからRogueWaveに切り替えることができます。

+0

非常に有益な返信です。 '_USE_OLD_RW_STL'が定義されていると、FastMMはプロジェクトで使用されているコンテナのリークを報告しません(' std :: vector'' std :: list'' std :: deque')。どうもありがとうございました。今すぐメモリリークレポートを読むのはずっと簡単です。 – bboydushko

+0

私が気付いたもう一つのことは、 'std :: cout'の使い方もリークを報告します。幸いなことに、私たちのコードには多くはありませんが、報告書に表示されているものを止めるために別の「魔法の条件付き定義」を知っていれば素晴らしいでしょう。例: 'std :: cout <<" hello "<< endl;'レポート: 13 - 20バイト:不明x 1 21 - 36バイト:std :: codecvt x 1 、不明x 2 37 - 52バイト:不明x 2 53 - 68バイト:std :: ctype x 1、__rwstd :: locale_imp x 2 85 - 100バイト:不明x 2 485 - 532バイト:不明x 3 、 'printf(" hello \ n ");'はリークを報告しません – bboydushko

関連する問題