これは確かに動作しませんでした。しかし、物事は変化しています。 Cランタイムライブラリwas changed in VS2012、それはもはや独自のヒープをもう作成しません。 VS2015の場合、このCのコード:\プログラムファイル(x86の)\ Windowsのキット\ 10 \ソース\ 10.0.10240.0 \ ucrt \ヒープの\ heap_handle.cppは関連しています。
// Initializes the heap. This function must be called during CRT startup, and
// must be called before any user code that might use the heap is executed.
extern "C" bool __cdecl __acrt_initialize_heap()
{
__acrt_heap = GetProcessHeap();
if (__acrt_heap == nullptr)
return false;
return true;
}
注意GetProcessHeap(への呼び出し) Marshal.AllocHGlobal()が割り当て元と同じヒープを返します。だから、Marshal.FreeHGlobal()で割り当てを解除したときに、デバッグヒープからの例外やリークが発生することはありません。
CoTaskMemAlloc()の場合とほとんど同じです。関数にシングルステップ、私は以下を参照してください。
7638D1E1 mov esi,dword ptr [g_CMalloc (76485EE0h)]
7638D1E7 push dword ptr [ebp+8]
7638D1EA mov esi,dword ptr [esi+0Ch]
7638D1ED cmp esi,offset CRetailMalloc_Alloc (763732C0h)
7638D1F3 jne CoTaskMemAlloc+44h (7638D214h)
7638D1F5 push 0
7638D1F7 push dword ptr [g_hHeap (76485E68h)]
7638D1FD call dword ptr [[email protected] (76488228h)]
はg_hHeap
変数の使用を注意してください。 GetProcessHeap()が返す値と同じ値を持つことがわかります。再び、と解放すると、割り当て解除関数のいずれもはうまく動作します。
これは私がWindows 10から入手したことに注意してください。古いバージョンのWindowsは同じように動作しません。そして、CRetailMalloc_Allocは、予期せぬ使い方をするあまり楽しくないランダマイザです。
これは確かに役立つものであり、プログラムが失敗する可能性はあまりありませんが、アプリをテストするときは実際には役に立ちません。嫌な、本当に、それは "私のマシン上でのみ動作する"障害モードを呼び出す。 Bah。
エラーが発生した場合、コードは必ず失敗するとは限りません。時にはそうなるでしょうが、時にはそうではありません。あなたがmallocで割り当てて、CoTaskMemFreeで割り当てを解除すると、リークします。私はあなたの漏れの検出が間違っていると思います。 –
私はCoTaskAllocMem/free、AllocHGlobal/freeをこの順番で試しました。同じポインタを返します。だからそれは確かに漏れていない。また、malloc(一度に1MB)を使って20GBを割り当てようとした後、P/InvokeのデフォルトとFreeHGlobal/CoTaskFreeMemで解放しました。リークなし(メモリ使用量の増加なし)。私が自由な機能を呼び出さなければ、プロセスはすぐに風船になる。 – MichaelGG
非常に大きなメモリブロックを割り当てていますか?おそらくすべてのアロケータがそれを 'VirtualAlloc'への直接呼び出しに委譲します。一握りのバイトを割り当ててみてください。 –