potisanのプログラミングメモ

趣味のプログラマーがプログラミング関係で気になったことや調べたことをいつでも忘れられるようにメモするブログです。はてなブログ無料版なので記事の上の方はたぶん広告です。記事中にも広告挿入されるみたいです。

C++ VariantToStringの戻り値はCoTaskMem関係

<propvarutil.h>VariantToString関数は新しく割り当てたメモリを返しますが、そのメモリを解放すべきかどうかの記載が一切ありません。CoGetMallocで取得したIMallocGetSizeは正しい値を返すので、おそらくCoTaskMemFree関数で解放すればよいのではないかと想像します。

なお、PropVariantToStringAlloc関数CoTaskMemFree関数が必要であると明記されています。

#pragma comment(lib, "propsys.lib")
#define STRICT
#include <Windows.h>
#include <propvarutil.h>

#include <ShlObj.h>

int main()
{
    VARIANT var1;
    HRESULT hr = InitVariantFromString(L"TEST", &var1);
    LPWSTR psz = nullptr;
    hr = VariantToStringAlloc(var1, &psz);

    IMalloc* pMalloc;
    hr = CoGetMalloc(1, &pMalloc);
    size_t size = pMalloc->GetSize(psz); // 10
    CoTaskMemFree(psz);

    // メモリ解放後に繰り返してもエラーは発生しない。
    hr = VariantToStringAlloc(var1, &psz);
    size = pMalloc->GetSize(psz); // 10
    CoTaskMemFree(psz);

    pMalloc->Release();

    return 0;
}

文字列に強制変換する必要がなければ、VARIANT内部の文字列アドレスを返すVariantToStringWithDefault関数やVariantGetStringElem関数を使うのもありかなと思います。