BSTRのメモリリーク対策

BSTRはメモリリークの原因になりやすい。
対策がいくつかあるので書いておく。

_bstr_tの利用

リークの発生するパターン
//Update static text with new value
BSTR tmpBStr;
m_pObject1->get_ObjectString(&tmpBStr);
_bstr_t tmpbstr(tmpBStr, FALSE); //necessary to avoid a memory leak
SetDlgItemText(IDC_CURPROPVAL, tmpbstr);

リークの発生しないパターン
//Update static text with new value
BSTR tmpBStr;
m_pObject1->get_ObjectString(&tmpBStr);
_bstr_t tmpbstr;
tmpbstr= tmpBStr; //Caution: Memory leak occurs
SetDlgItemText(IDC_CURPROPVAL, tmpbstr);

2つの違いは、_bstr_tのコンストラクタを利用するかどうか。

上の例では、 = 演算子で_bstr_tにBSTRが代入されます。
この場合、_bstr_tの中で新しく作成されたBSTRはデストラクタで自動的に解放されますが、代入もとのBSTRは解放されません。
下の例では、_bstr_tのコンストラクタ第2引数をfalseにすることで、新しくBSTRの情報を作成するのではなく、引数のBSTRをそのまま使うことを意味する。~ その為、_bstr_tのデストラクタで、引数に指定されたBSTRが解放されます。

参考資料

  • ATL サーバー用の単純な MFC クライアントのインプリメント→BSTR と文字列の操作