Windowsのメモリアロケーション関数の関係について整理した
C++/CLI
で、new
演算子で確保したアンマネージドメモリをMarshal::FreeHGlobal()
で解放しようとするとエラーになってなぜだろうと思い調べた。
ソース抜粋
- メモリ確保
unsigned char *test = new unsigned char[100];
- 問題ないメモリ解放
//これは問題ない delete [] test;
- 例外が起きるメモリ解放
//こう書くと例外
System::Runtime::InteropServices::Marshal::FreeHGlobal(IntPtr(test));
MSDNのドキュメントとVisual Studioの逆アセンブリ機能で調べると以下が判明
よく見ると、メモリ確保のメカニズムがことなるので正しい関数で解放しなきゃいけないと書いてある。 たぶん、今回の問題も同じようにメモリ確保と対になる正しい関数でメモリ解放しなさいということなんだろう。
Because the different heap allocators provide distinctive functionality by using different mechanisms, you must free memory with the correct function. For example, memory allocated with HeapAlloc must be freed with HeapFree and not LocalFree or GlobalFree. Memory allocated with GlobalAlloc or LocalAlloc must be queried, validated, and released with the corresponding global or local function.
引用元:Comparing Memory Allocation Methods
つまりこういうことなんだろう
メモリ確保関数 | メモリ解放関数 |
---|---|
HeapAlloc | HeapFree |
GlobalAlloc | GlobalFree |
LocalAlloc | LocalFree |
Marshal::AllocHGlobal | Marshal::FreeHGlobal |
new演算子 | delete演算子 |
malloc | free |