CComPtrのRleaseメソッドとDetachメソッドの違いについて

解決


キキ  2009-07-15 20:08:05  No: 70591

CComPtr<hoge> h;
for (int i = 0; i < max; i++)
{
    h.Relase();
    ret = dosomething(&h);
    h->hogehoge();
}

CComPtr<hoge> h;
for (int i = 0; i < max; i++)
{
    h.Detach();
    ret = dosomething(&h);
    h->hogehoge();
}

・RleaseメソッドよりDetachメソッドを使用したほうがパフォーマンスがよいか?
・パフォーマンスがいいのならDetachメソッドを使用するが、Detachメソッドを使用した場合メモリリークは起きていないか

この2つがわからないんでが知っている方がいたら教えてくださいませんか?


...  2009-07-15 21:26:09  No: 70592

>・RleaseメソッドよりDetachメソッドを使用したほうがパフォーマンスがよいか?
>Detachメソッドを使用した場合メモリリークは起きていないか
自分でやってみればいいのに。


aetos  2009-07-15 21:27:56  No: 70593

用途が違うので、パフォーマンスだけを根拠にどっちを使うか決めるものではありません。

> Detachメソッドを使用した場合メモリリークは起きていないか

Release すべきところで Detach を使えば起きる可能性はあります。


  2009-07-15 22:05:19  No: 70594

DetachはReleaseせずにスマートポインターからCOMインスタンスを切り離したいときに使うもの


subaru  2009-07-15 22:07:14  No: 70595

Release にしても Detach にしても呼んだ後は
もうそのインスタンスは使っちゃいけないと思うのだけど
ちゃんと動きますか?


キキ  2009-07-15 22:24:02  No: 70596

皆さん回答ありがとうございます

>...さん
パフォーマンスに関しては自分で調べれますね。反省します
メモリリークの調べ方ってあるのですか?

>aetosさん
>Release すべきところで Detach を使えば起きる可能性はあります。
この状況がわからないのです…。

>あさん
>DetachはReleaseせずにスマートポインターからCOMインスタンスを切り離したいときに使うもの
スマートポインタから切り離したら、誰が解放するのか?が気になりまして。
だからメモリリークを起こすのかなと思ったんですけど。間違っていますかね?
MSDNをみたらDetachメソッドはポインタの所有権を解放します。
Releaseメソッドはインターフェイスを解放します。
この違いもわかりません。

>subaruさん
問題なく動いてます。


aetos  2009-07-15 22:43:16  No: 70597

> スマートポインタから切り離したら、誰が解放するのか?が気になりまして。

プログラマがしなければ誰もしません。

> MSDNをみたらDetachメソッドはポインタの所有権を解放します。
> Releaseメソッドはインターフェイスを解放します。
> この違いもわかりません。

まず、所有者(所有権)とは何かを考えます。
所有者とは、この場合、CComPtr が保持している生ポインタが指すインターフェイスを開放する者のことです。生ポインタに対して IUnknown::Release を呼ぶ者と言い換えてもよいです。
CComPtr はインターフェイス ポインタに対する所有権を持っています。これは、CComPtr がデストラクトされる際に、その生ポインタを開放するということです。
これは Release と同じことです。

Detach は所有権を放棄します。
つまり、デストラクタで生ポインタを開放しなくなります。結果、CComPtr のデストラクト後も生ポインタは有効なままです。

CComPtr のデストラクト後も生ポインタが有効である必要がある場合には Detach を使います。かつ、その場合は別途 IUnknown::Release を呼ぶ必要があります。
もうそのポインタを使用しない場合には Release を呼びます。

> 自分でやってみればいいのに。

やってみてもメモリリークはなかなか確認しづらいと思います。

> ちゃんと動きますか?

メモリリークを無視すれば動きます。
CComPtr::operator & は、CComPtr が生ポインタを保持していない場合に、新しいポインタ(の所有権)を獲得するためのものです(Attach と同じです)。
ですから、dosomething は hoge にアクセスする関数ではなく、新しい hoge インスタンスを作る関数と思われます。
そのため、開放後の &h を dosomething に渡すのはまったく正当です。


aetos  2009-07-15 22:44:13  No: 70598

> 問題なく動いてます。

「問題なく動いている」と「問題なく動いているように見える」は違います。
今回のケースで Detach を使っていれば、短期的には問題なく動いているように見えても、いずれメモリを食いつぶします。


  2009-07-15 23:11:23  No: 70599

そのための戻り値


キキ  2009-07-15 23:50:43  No: 70600

皆さん回答ありがとうございます

DetachとRelaseの違いがわかりました。
ポインタを解放する必要があるのでReleaseを使用します

ところで…。ループ内でRelaseするんだったらループ内で宣言するのと
同じですよね?

CComPtr<hoge> h;
for (int i = 0; i < max; i++)
{
    h.Relase();
    ret = dosomething(&h);
    h->hogehoge();
}

よりも
for (int i = 0; i < max; i++)
{
    CComPtr<hoge> h;
    ret = dosomething(&h);
    h->hogehoge();
}
のコードのほうがすっきりしますよね。


subaru  2009-07-16 00:45:53  No: 70601

ああ、インスタンスを使いまわしたいというわけか。
好みの問題もあるけど後者のコードの方がわかりやすいかも。


aetos  2009-07-16 00:52:15  No: 70602

> のコードのほうがすっきりしますよね。

そうですね。
この場合は CComPtr がデストラクトされる際に Release を呼びますから、明示的に Release する必要がありません。そのためのスマートポインタですしね。
若干パフォーマンスが悪くなる気がします(自信なし)が、スマートポインタはごく小さなオブジェクトなので劣化も微々たるものだと思います。それなら読みやすい方がメリットがあるでしょうね。


キキ  2009-07-16 04:20:08  No: 70603

皆さん最後まで回答してくれてありがとうございます
とても助かりました。
また質問した時にはよろしくお願いします


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加