51365


.NETのIntptr構造体に関する質問です。

C#でポインタを利用する際、Marshal.AllocHGlobalでメモリ領域を確保しMarshal.FreeHGlobalで確保した領域を解放しますが、Marshal.AllocHGlobalで確保された領域はガベージコレクションで自動的に解放されないのですか？


CC BY-SA 4.0
2018-12-19T13:37:19.807
51356
2018-12-19T23:17:30.710
2018-12-19T23:02:47.030
4236
25717
question
c# .net
.NETのIntptr構造体に関する質問です。


解放されません。  
<https://docs.microsoft.com/ja-
jp/dotnet/api/system.runtime.interopservices.marshal.allochglobal>  
解説を読むうえで重要なキーワードは「マネージ」「アンマネージ」で、

  * マネージ

.NET Framework の管理下にあって、オブジェクトが自動 gc されるもの。 [c#](/questions/tagged/c%23 "'c#'
のタグが付いた質問を表示") や [visualbasic](/questions/tagged/visualbasic "'visualbasic'
のタグが付いた質問を表示") で `new` するとこっち。マネージメモリを Visual C/C++ native DLL に直接渡すことはできない。

  * アンマネージ

.NET Framework の管理下にないもの。端的には Win32 Native なコードやメモリのこと。つまり Visual C/C++
で書いたコードや、直接使えるメモリのこと。アンマネージのほうが歴史的に古い存在なので、マネージコードからアンマネージコードを呼び出す際に「マーシャリング」することで、間接的にマネージコードからアンマネージメモリを使うことはできるようになっている（マーシャラの性能が高いかと問われると微妙かも）

この件、マニュアルにきっちり「アンマネージ」と明記されていますので gc 対象にはならないと読めます。すなわち、自分で
`Marshal.FreeHGlobal` する必要があります。


CC BY-SA 4.0
2018-12-19T20:46:16.467
51365
2018-12-19T20:46:16.467
8589
51356
answer


C#でポインタを利用する方法は複数あります。

例えば[`fixed`ステートメント](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-
reference/keywords/fixed-
statement)を使用することで、指定したマネージメモリに対するGCを一時的に停止させ、ポインター操作を行うことができます。あくまで一時的に停止しているだけなので、`fixed`ステートメントを抜けた段階でGCは再開され、不要になったオブジェクトは自動的に解放されます。

[`Marshal.AllocHGlobal`](https://docs.microsoft.com/ja-
jp/dotnet/api/system.runtime.interopservices.marshal.allochglobal?view=netframework-4.7.2)はポインターを扱う別の方法です。ちなみに名前に反して`GlobalAlloc`ではなく`LocalAlloc`を用いられています。`LocalAlloc`で確保したメモリーアドレスを取得することで、ポインター操作を行うことができます。こちらはGC管理外のメモリーを取得することが目的ですので、当然ながらGCが解放することはありません。

[IntPtr構造体](https://docs.microsoft.com/ja-
jp/dotnet/api/system.intptr?view=netframework-4.7.2)はあくまでメモリーアドレスを表現するだけであり、メモリー確保方法については関与していません。


CC BY-SA 4.0
2018-12-19T23:17:30.710
51366
2018-12-19T23:17:30.710
4236
51356
answer