IMallocとCoTaskMemAlloc

[戻る]
2005/02/11(金) 13:08:28
こんにちは
たびたびすみませんが、また質問があります

開発環境です
WinXP、VC++6.0、MFC、SDI

現在ITEMIDLISTの操作に取り組んでいます

取得したITEMIDLISTを保存するために、
独自に確保したメモリにIDリストをコピーするという処理をしています

いくつかのサンプルを見て回りましたが、ITEMIDLISTを保存するメモリは
IMalloc::Alloc()で確保しているものばかりでした
しかしIMalloc::Alloc()を調べてるうちに、CoTaskMemAlloc()という関数を見つけまし
た

この関数をMSDNで調べてみると
「IMalloc::Alloc()と同じ方法でメモリを確保します」
といったような記述がしてありました
英文だったので訳が間違っている可能性はあるのですが・・・

で、今までIMalloc::Alloc()とIMalloc::Free()を使用していた部分を
CoTaskMemAlloc()とCoTaskMemFree()に置き換えてみました

そして動作させてみたところとりあえず動作に違いは見られませんでした

IMallocを使用する場合、
使うたびにSHGetMalloc()とIMalloc::Release()をする必要がありますが、
CoTaskMemAlloc()と同Free()の場合はその必要もなく、
ソースがすっきりするという利点はあると思います

ここで質問です

まず、大前提として、この用途にCoTaskMemAlloc()と同Free()を利用するのは
正しい手法なのでしょうか
MSDN(英語)を見るとITEMIDLIST関連の文書ではIMallocを使うように書いてある感じが
します
英語は苦手なので完全に読み解けたわけではないんですけどね・・・

上でも書きましたがCoTaskMemFree()が「IMalloc::Alloc()と同じ方法で・・・」
ということならば、こちらを使っても大丈夫な気はするんですが

もう一つです

このように自分で取得、開放をするメモリならばCo系かIMalloc系で統一できます
しかし、例えば・・・
IEnumIDList::Nextで取得されるLPITEMIDLISTを開放するときなどに
CoTaskMemFree()を使用してもいいのでしょうか?
参考にしたサンプルでもほとんどはIMalloc::Free()を使用していますが、
1例だけCoTaskMemFree()を使用しているものを見つけました

実際にやってみても動作は正常に見えます

もしかしたらどちらでもいいのかもしれませんが、
サンプルがほとんどIMallocを使用していることから、
それが本来のやり方なのかと思い質問しました

どなたかわかる方いましたらお願いします

2005/02/11(金) 13:20:05
書き込んだ直後ですが自己レスです

継続して調べていたところ次のようなものを見つけました
http://forums.belution.com/ja/vc/000/070/62s.shtml

> CoTaskMemFree は
> CoGetMalloc → IMalloc::Free → IMalloc::Release
> とやっているだけです。

他の質問BBSの過去ログのようです

CoTaskMemAlloc()およびCoTaskMemFree()は内部で
IMallocを取得しIMalloc::Alloc()およびIMalloc::Free()を呼び、
そして開放している

つまり仮にCoTaskMemAlloc()を使用することでソースがすっきりしたとしても、
処理量としてはほぼ同じになるというこということでしょうか

逆に、メモリを確保、開放する回数が多い場合は、
IMallocを1度確保し、そのポインタを使いまわすことで
SHGetMalloc()とIMalloc::Release()の回数を減らし、
全体の処理量を減らしたほうがいいということでしょうか

アドバイスがあればよろしくお願いします

2005/02/12(土) 15:54:10
自己レスその2です

上で書いた

> CoTaskMemFree は
> CoGetMalloc → IMalloc::Free → IMalloc::Release
> とやっているだけです。

のCoGetMalloc()がSHGetMalloc()とは違うのかなと疑問に思っていて
調べてみたら次のような情報を見つけました

http://www.snark.co.jp/soft/faq/vc_q2.htm
ここの「Q10」の回答に
http://www.snark.co.jp/soft/faq/vc_a2.htm#Q10

> Shlobj.hを見ると,
> // Notes:
> // In next version of Windowso release, SHGetMalloc will be replaced by
> // the following macro.
> // #define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem)
> と書いてあります.結局一緒なんですね

と書いてありました

もしそうだとすると
SHGetMalloc() → IMalloc::Alloc() → IMalloc::Release()
と
CoTaskMemAlloc()
は完全に同じ動きをすると見ていい気もしてきますが・・・実際どうなんでしょう

ただ、

> CoTaskMemFree は
> CoGetMalloc → IMalloc::Free → IMalloc::Release

このCoTaskMemFree()の内部動作が実際にこの通りであるならば、ですが
CoTaskMemAlloc()とCoTaskMemFree()に関してもいろいろ調べてみてますが、
実際に内部でどんな処理をしているかと書いてあるところが見つからないもので・・・

引き続き調べてはみますが、もし何か知っている方いましたらお願いします

シャノン 2005/02/12(土) 17:37:04
> もしかしたらどちらでもいいのかもしれませんが、
> サンプルがほとんどIMallocを使用していることから、
> それが本来のやり方なのかと思い質問しました

たぶん、どっちでもいいんだと思います。根拠は

> この関数をMSDNで調べてみると
> 「IMalloc::Alloc()と同じ方法でメモリを確保します」
> といったような記述がしてありました

これで十分だと、俺は思います。

不安なら、ITEMIDLIST 専用の ILFree とかいう関数もあります。

2005/02/12(土) 18:20:54
[[解決]]
シャノンさん、レスありがとうございます

やはり大丈夫っぽいですか
名前が違うと機能も違うのかなと思ってしまうのですよね
さらに英語に弱いので、それっぽいことが書いてあっても自身がもてないというのが
(↑プログラム関係の英語ぐらいまともに読めるようになりたい・・・)

またILFreeも調べてみました

ILFree以外にもIL系関数がいくつかありました
なんというか見事に自作したのと同じような関数があったり、
さらに便利そうなのもいくつかあったり
おかげで予想していなかった手法を取り入れるヒントにもなりました

対応状況がWindows2000以降とのことで、
現状ではどのあたりのWindowsのバージョンに対応させるかはまだ少しあいまいですが、
場合によってこのあたりの関数も取り入れてみようかと思います

どうもありがとうございました

古いスレッドには追加発言できません。