3

C++ Builder で VirtualTreeView を使用し、次のような構造で使用します。

struct TVTNodeData
   {
   int Index;
   UnicodeString Caption;
   }

これを持つループを使用して、ツリーのノードを事前に入力します。

TVirtualNode *Node = VTree->AddChild(NULL);
pNode = (TVTNodeData *)VTree->GetNodeData(Node);
pNode->Index = 1;
pNode->Caption = "Whatever";

ツリーをクリアしてリロードしても、アプリケーションのメモリが常に増加していることに気付きました (メモリ リーク)。このページ - http://www.remkoweijnen.nl/blog/2010/06/09/memory-leaks-when-using-virtual-treeview-component/OnFreeNodeは、イベントで Finalize() を実行することを推奨しています。これまでのところ良い。

ただし、C++ には Finalize() はありません。イベントで試してみたところpNode->Caption=""OnFreeNodeメモリはそれほど劇的に割り当てられなくなりましたが、それでも少しです。空になっても UnicodeString への参照が残っている可能性があると思います (参照カウント > 0)。

OnFreeNodeC++ で UnicodeString のイベントでノード データを解放するにはどうすればよいですか? すべての参照カウントがゼロになるまで UnicodeString が割り当てられることはわかっています。では、参照カウントを強制的にゼロにするにはどうすればよいでしょうか?

また、ノードが割り当てられている場合はどうなりますかOnNodeInit- イベントにも同じことが当てはまりOnFreeNodeますか?

TVTNodeData 構造が純粋に仮想である場合はどうなりますか? AddChild も OnNodeInit も使用せずにノードが表示されたり初期化されたりすることはありません。

更新:後で、メモリ使用量を誤って測定していたこと、および文字列を空の文字列に設定するだけでメモリ データをクリアするのに十分であることがわかりました。しかし、ロブ・ケネディが以下の回答で示唆しているように、 struct ~destructor を呼び出すことは、 Finalize と同等であり、構造全体をクリアするため (より多くの文字列が含まれている場合) よりも簡単です。

4

2 に答える 2

8

DelphiFinalizeには、レコード内のコンパイラ管理型を解放する効果があります。C++ では、これは通常、型のデストラクタの仕事です。OnFreeNodeイベント ハンドラで、データ型のデストラクタを直接呼び出します。

TVTNodeData* const pNode = static_cast<TVTNodeData*>(Sender->GetNodeData(Node));
pNode->~TVTNodeData();

UnicodeStringこれにより、オブジェクトのデストラクタが呼び出され、関連する文字データが解放されます。ツリー コントロールがノードに を割り当てるとき、TVTNodeDataそれはオブジェクト自体と同じメモリ ブロックにあるTVirtualNodeため、単に を呼び出すことはできませんdelete

ツリー コントロールは、すべてのビットがゼロでデータを初期化します。データ内に正しい初期化ではないオブジェクトがある場合 (正式には、POD 以外のすべての型が含まれます)、イベントでデータのコンストラクターを呼び出す必要があります。これを行うには、 placement newOnInitNodeを使用します。例えば:

TVTNodeData* const pNode = static_cast<TVTNodeData*>(Sender->GetNodeData(Node));
new (pNode) TVTNodeData();

これにより、追加のインスタンスTVTNodeDataにメモリを割り当てることなく、メンバーのコンストラクターが呼び出されます。TVTNodeData

ノードが初期化されていない場合は、ファイナライズもされません。イベントはOnInitNode決して実行されないため、ツリーはノードが初期化されていないことを認識します。初期化されていないノードはファイナライズされないため、心配する必要はありません。

于 2012-04-17T16:19:30.287 に答える
2

おそらく表示されなかったために、すべてのノードが検証されたわけではないと思います。AddChildの後にValidateNodeを呼び出してみてください。

于 2012-04-17T13:59:19.647 に答える