Malloc()とHeapAlloc()の違いは何ですか?私が理解している限り、mallocはHeapAllocと同じように、ヒープからメモリを割り当てます。
それで、違いは何ですか?
ありがとう!
どちらもヒープからメモリを割り当てるのは正しいことです。ただし、違いがあります。
malloc()
は移植性があり、標準の一部です。HeapAlloc()
は移植性がなく、Windows API関数です。Windowsでは、malloc
の上にHeapAlloc
が実装される可能性が十分にあります。 malloc
はHeapAlloc
よりも速いと思います。
HeapAlloc
はmalloc
よりも柔軟性があります。特に、どのヒープから割り当てるかを指定できます。これは、プロセスごとに複数のヒープに対応します。
ほとんどすべてのコーディングシナリオでは、malloc
ではなくHeapAlloc
を使用します。質問にC++をタグ付けしたので、new
!を使用することを期待します。
実際、malloc()(および他のCランタイムヒープ関数)はモジュールに依存します。つまり、1つのモジュール(つまりDLL)のコードでmalloc()を呼び出す場合、同じモジュールのコード内でfree()を呼び出す必要があります。または、かなり悪いヒープ破損が発生する可能性があります(これは十分に文書化されています)。 malloc()の代わりにGetProcessHeap()でHeapAlloc()を使用すると、new演算子とdelete演算子をオーバーロードしてそのようなものを使用できるため、モジュール間で動的に割り当てられたオブジェクトを渡すことができ、メモリがメモリブロックへのポインタが外部モジュールに渡されると、1つのモジュールが別のモジュールのコードで解放されます。
Visual C++では、関数malloc()
または演算子new
が最終的にHeapAlloc()
を呼び出します。コードをデバッグすると、関数_heap_alloc_base()
(ファイル_malloc.c
_内)がreturn HeapAlloc(_crtheap, 0, size)
を呼び出していることがわかります。ここで__crtheap
_は、 HeapCreate()
。
関数HeapAlloc()
は、メモリオーバーヘッドを最小化するために適切な仕事をします。割り当てごとに最低8バイトのオーバーヘッドがあります。私が見た最大のものは、1バイトから100,000バイトの範囲の割り当てに対して、割り当てごとに15バイトです。ブロックが大きいほどオーバーヘッドが大きくなりますが、割り当てられた合計の割合がペイロードの2.5%未満のままになります。
HeapAlloc()
をカスタムルーチンでベンチマークしていないため、パフォーマンスについてコメントすることはできませんが、HeapAlloc()
を使用した場合のメモリオーバーヘッドに関しては、オーバーヘッドは驚くほど低くなっています。
malloc
は、C標準ライブラリ(およびC++標準ライブラリ)の関数です。
HeapAlloc
はWindows API関数です。
後者では、割り当てるヒープを指定できます。これは、異なるスレッドでの割り当て要求のシリアル化を回避するのに役立つと思います(HEAP_NO_SERIALIZE
フラグ)。
乾杯
複数のDLLが(LoadLibrary/Freelibraryを介して)行き来する可能性があり、メモリが1つのDLL内で割り当てられ、別のDLLで解放される場合(前の回答を参照)、HeapAllocおよび関連する関数は、成功したメモリ共有。
スレッドセーフで、おそらく博士課程の博士によって高度に最適化されたHeapAllocは、malloc/freeを使用してあまり共有できないコードが失敗するあらゆる種類の状況で機能するようです。
私たちはC++の組み込みショップであるため、システム全体で演算子new/deleteをオーバーロードし、HeapAlloc(GetProcessHeap())を使用して、コードの移植性のためにスタブ(ターゲット)またはネイティブ(Windows)を使用できます。
これまでのところ、紛れもなくDLL、具体的には、各DLL load。
さらに、以下を参照できます。
https://msdn.Microsoft.com/en-us/library/windows/desktop/aa366705(v = vs.85).aspx
これは、WinApiメモリアロケーターによって管理されるHEAPの一部の機能(「HeapEnableTerminationOnCorruption」など)を有効にできることを意味します。
私が理解しているように、それはいくつかの基本的なヒープオーバーフロー保護を行います。これは、セキュリティの観点からアプリケーションの付加価値と見なされる可能性があります。
(たとえば、任意のコードを実行するよりも、アプリを(アプリの所有者として)クラッシュさせたい場合)
もう1つは、開発の初期段階で役立つ可能性があるため、実稼働に進む前にメモリの問題をキャッチできることです。
mallocは、コンパイラ固有のCランタイムライブラリ(CRT)によってエクスポートされた関数です。
CランタイムライブラリのDLL名は、Visual Studioバージョンからバージョンに変更されます。
HeapAlloc関数は、Windowsフォルダーにあるkernel32.dllによってエクスポートされます。
これはMSがそれについて言っていることです: http://msdn.Microsoft.com/en-us/library/windows/desktop/aa366533(v = vs.85).aspx
これまでに言及したことの1つは、「malloc関数にはランタイムに依存するという欠点があります。new演算子にはコンパイラに依存し、言語に依存するという欠点があります。」
また、「メモリを割り当てることができなかった場合、HeapAllocに例外を発生させるように指示できます」
したがって、プログラムを任意のCRTで実行する場合、またはCRTをまったく実行しない場合は、HeapAllocを使用します。おそらく、そのようなことをする人だけがマルウェア作成者になるでしょう。別の用途としては、CRTを使用する代わりに独自のヒープアロケータを作成する特定のメモリ割り当て/使用パターンを使用して、非常にメモリを集中的に使用するアプリケーションを作成する場合があります。