4

私はC++コードを持っています。しかし、メモリを適切に解放していません。どこが間違っているか教えてください。ここに私のコードがあります

1 void MyClass::MyFunction(void)
2 {
3    for (int i=0; i<count; i++)
4    {
5        _bstr_t xml = GetXML(i);
6        // some work
7        SysFreeString(xml);
8    }
9 }

GetXML (5 行目) は BSTR を返します。これでプログラムのメモリが増えます。しかし、SysFreeString (7 行目) の後、メモリは解放されません。ここで何が間違っていますか?

4

4 に答える 4

8

初め:

// This makes a copy.
// This is where the leak is. You are leaking the original string.
_bstr_t xml = GetXML();

// You want to use this, to attach the BSTR to the _bstr_t
_bstr_t xml = _bstr_t(GetXML(), false);

第二に、これをしないでください:

SysFreeString(xml); 

クラスがそれ_bstr_tを行います。

第 3 に、BSTR はすぐにメモリを OS に解放しません。SysAllocString を高速化するために、最近使用した文字列をキャッシュします。SysFreeString の後で、メモリ使用量がすぐに下がるとは思わないでください。

デバッグ目的でこの動作を制御できます。

最後に、タスク マネージャーでメモリ使用量を表示するときは、[ワーキング セット] 列ではなく [コミット サイズ] 列を確認する必要があります。[メニュー] -> [表示] -> [列の選択] に移動して、列を表示します。また、これは実際には一定期間にわたってのみ役立つことに注意してください。メモリはすぐに OS に解放されない可能性がありますが、リークがなければ、何時間にもわたって永遠に上昇することはありません。

于 2012-10-22T12:29:36.873 に答える
1

私はあなたが使用する必要があると思います:

xml.Attach(GetXML(i));

operator= 実際に新しい値を割り当てているように見えます-つまり、コピーしています。GetXML によって返されるその値は、解放されないままです。

また、SysFreeString(xml); も必要ありません。

于 2012-10-22T12:16:53.557 に答える
0

タスク マネージャーは、プロセスに割り当てられたメモリの量のみを提供します。C++ がメモリを解放する (C の解放) 場合、必ずしもメモリがオペレーティング システムに返されるとは限らないため、プロセスが終了するまで、タスク マネージャーは必ずしもメモリの進行状況を表示しません。

タスクマネージャーが表示できるのは、メモリを割り当て続けて解放しないと、プロセスのメモリサイズが増加し続けることです。これが発生した場合、メモリリークが発生している可能性があります.

プログラミングするときは、メモリ プロファイラーを使用して、メモリを解放しているかどうかを確認する必要があります。Windows では、Rational の Purify を使用してこの情報を取得しましたが、コストがかかります。MS C ランタイムを使用してメモリを追跡できます。MSDNはここで概要を提供し、リンクを読んでフォローしてください。

コードに関して、および他のコメントと回答によると、_bstr_tクラスを使用するポイントの1つは、メモリおよびその他のリソース管理を行うことであるため、SysFreeStringを呼び出すべきではありません

于 2012-10-22T12:29:39.460 に答える