プロが教える店舗&オフィスのセキュリティ対策術

C#におけるアンマネージド関数(Win32API)呼び出し時におけるメモリの扱い方について教えていただきたいことがございます。

.NET Framework上で呼び出したWin32API関数にて、あるデータを格納したウハンドル(ポインタ)が返り値とします。
例えば、CreateEllipticRgn()はHRGN型のリージョンハンドル(C#上ではIntPtrとして処理)を返してきます。
この場合には返り値のハンドルが指す番地には実体(リージョンデータ)があるはずです。
#そもそもこの時点で間違っていたらご指摘下さい(^^;
アプリケーション終了時にGCにてCreateEllipticRgn()にて確保された返り値のハンドル先の領域は解放されるのでしょうか?

例としてCreateEllipticRgn()を挙げましたが、一般的な話としてアンマネージド関数内で確保された領域の扱いについてご指摘いただけると有り難いです。
宜しくお願い致します。

A 回答 (1件)

マネージド ( managed:管理されている ) とかアンマネージド ( unmanaged:管理されていない ) とかって、.NET Framework の中核である Common Language Runtime ( CLR ) によって管理されているか、いないか、を指しています。


アンマネージドコードによって確保されたメモリ(アンマネージドメモリ)は CLR によって管理されていない(というか、できない)ので、GC によるメモリ解放もされません。
アプリケーション終了時には、OS によって、そのアプリケーションが使用していたメモリは解放されますので、アンマネージドメモリが解放されずに残っていても、アプリケーション終了時には解放されます。
しかし、アンマネージドメモリを解放しないままアプリケーションを動かしていると、アプリケーションが起動している間はメモリがどんどん消費されてメモリがひっ迫する可能性が出てくるので、アンマネージドメモリは不要になった時点で解放すべきでしょう。
解放の方法は、確保された方法によっていろいろです。
例えば、

HRGN などの GDI オブジェクト:DeleteObject を使用
HANDLE 型の Kernel オブジェクト:CloesHandle を使用 ( FindFirstFile の場合は FindClose )
GlobalAlloc で確保されたメモリ:GlobalFree を使用

となっています。( FindFirstFile のように、他にも例外があるかも)


>この場合には返り値のハンドルが指す番地には実体(リージョンデータ)があるはずです。

現状では正しいと思いますが、仕様としては保証されていないと思います。
    • good
    • 0
この回答へのお礼

丁寧なご回答を有難う御座いました。
やはり明示的に解放しなければならないのですね。
C#上からでしかWin32APIを触ったことがなくて、ハンドルから実体の解放方法が分からなかったのですが、これについても勉強になりました。
大変助かりました。
有難う御座いました。

お礼日時:2011/07/17 01:52

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!