、、、などVirtualAlloc
、 Windows環境でメモリを割り当てる方法はたくさんあります。HeapAlloc
malloc
new
したがって、それらの違いは何ですか?
、、、などVirtualAlloc
、 Windows環境でメモリを割り当てる方法はたくさんあります。HeapAlloc
malloc
new
したがって、それらの違いは何ですか?
各 API はさまざまな用途に使用されます。また、メモリを使い終わったら、正しい割り当て解除/解放関数を使用する必要があります。
多くのオプションを提供する低レベルの Windows API ですが、主にかなり特殊な状況にある人々に役立ちます。(編集:4KBではない)より大きなチャンクでのみメモリを割り当てることができます。必要な状況もありますが、これらの状況のいずれかになるとわかります。最も一般的なのは、メモリを別のプロセスと直接共有する必要がある場合です。汎用のメモリ割り当てには使用しないでください。割り当て解除に使用VirtualFree
します。
よりも大きなチャンクではなく、必要なサイズのメモリを割り当てますVirtualAlloc
。HeapAlloc
いつ呼び出す必要があるかを認識し、VirtualAlloc
自動的に呼び出します。に似malloc
ていますが、Windows 専用であり、さらにいくつかのオプションを提供します。一般的なメモリ チャンクの割り当てに適しています。一部の Windows API では、これを使用して渡すメモリを割り当てるか、そのコンパニオンHeapFree
を使用して返されるメモリを解放する必要があります。
メモリを割り当てる C の方法。C++ ではなく C で書いていて、たとえば Unix コンピュータでもコードを動かしたい場合や、誰かがそれを使う必要があると具体的に言っている場合は、これをお勧めします。メモリを初期化しません。などの一般的なメモリ チャンクの割り当てに適していHeapAlloc
ます。シンプルな API。割り当て解除に使用free
します。Visual C++ のmalloc
呼び出しHeapAlloc
.
メモリを割り当てる C++ の方法。C++ で記述している場合は、これをお勧めします。割り当てられたメモリにもオブジェクトを配置します。delete
割り当て解除 (またはdelete[]
配列) に使用します。Visual Studioは をnew
呼び出しHeapAlloc
、呼び出し方によっては、オブジェクトを初期化する場合があります。
最近の C++ 標準 (C++11 以降) では、手動で を使用する必要がある場合delete
は、間違っているため、代わりにスマート ポインターのようなものを使用する必要がありますunique_ptr
。C++14以降も同様ですnew
( などの関数に置き換えてmake_unique()
)。
SysAllocString
特定の状況で使用する必要があると言われるような、他にもいくつかの同様の機能があります。
VirtualAlloc
OS 仮想メモリ (VM) システムの特殊な割り当てです。VM システムでの割り当ては、アーキテクチャに依存する割り当ての粒度 (割り当ての粒度) で行う必要があります。VM システムでの割り当ては、メモリ割り当ての最も基本的な形式の 1 つです。VM の割り当てにはいくつかの形式があります。メモリは必ずしも専用または物理的に RAM にバックアップされているとは限りません (ただし、そうすることができます)。VM の割り当ては、通常、割り当ての特別な目的のタイプです。
HeapAlloc
は本質的に何malloc
であり、new
両方が最終的に呼び出すものです。これは、汎用割り当てのさまざまなタイプのシナリオで非常に高速に使用できるように設計されています。古典的な意味での「ヒープ」です。ヒープは実際には によってセットアップされますVirtualAlloc
。これは、最初に OS から割り当て領域を予約するために使用されます。によってスペースが初期化された後VirtualAlloc
、さまざまなテーブル、リスト、およびその他のデータ構造が構成され、HEAP の動作を維持および制御します。その操作の一部は、ヒープの動的なサイズ変更 (拡大と縮小)、ヒープを特定の用途 (特定のサイズの頻繁な割り当て) に適応させるなどの形式です。
new
とmalloc
は多少同じですが、本質的に;malloc
への正確な呼び出しです。ただし、[追加で] C++オブジェクトに割り当てられたメモリを構成できます。特定のオブジェクトについて、C++ は各呼び出し元のヒープに vtable を格納します。これらの vtable は実行用のリダイレクトであり、C++ に継承、関数のオーバーロードなどの OO 特性を与えるものの一部を形成します...HeapAlloc( heap-id-default )
new
_alloca()
やなどの他の一般的な割り当て方法_malloca()
は、スタックベースです。FileMappings は実際にはVirtualAlloc
、これらのマッピングが type であることを示す特定のビット フラグで割り当てられ、設定されますFILE
。
ほとんどの場合、そのメモリの使用と一致する方法でメモリを割り当てる必要があります;)。 new
C++ の場合malloc
、C の場合VirtualAlloc
、大規模または IPC の場合。
*** 注: によって行われた大規模なメモリ割り当ては、実際にはある程度のサイズ (数百 k または 16 MB または私が忘れたものですが、かなり大きい :)) 後HeapAlloc
に出荷されます。VirtualAlloc
*** 編集 IPC について簡単に述べましたが、この質問への回答者の誰も議論していない VirtualAlloc
、関連する非常に優れた点もあります。VirtualAlloc
VirtualAlloc
Exは、あるプロセスが別のプロセスのアドレス空間にメモリを割り当てるために使用できるものです。最も一般的には、これを組み合わせて使用し、CreateRemoteThreadを介して別のプロセスのコンテキストでリモート実行を取得します(同様にCreateThread
、スレッドは別のプロセスで実行されます)。
概要:
VirtualAlloc、HeapAlloc などは、さまざまな種類のメモリを OS から直接割り当てる Windows API です。VirtualAlloc は Windows 仮想メモリ システムのページを管理し、HeapAlloc は特定の OS ヒープから割り当てます。率直に言って、これらのいずれかを使用する必要はほとんどありません。
malloc は、プロセスにメモリを割り当てる標準 C (および C++) ライブラリ関数です。malloc の実装は通常、アプリの起動時に OS API の 1 つを使用してメモリのプールを作成し、malloc リクエストを行うときにそこから割り当てます。
new は、メモリを割り当て、そのメモリでコンストラクタを適切に呼び出す標準 C++ 演算子です。これは、malloc または OS API の観点から実装できます。その場合、通常、アプリケーションの起動時にメモリ プールも作成されます。
VirtualAlloc
===> sbrk()
UNIXの場合
HeapAlloc
====> malloc()
UNIXの場合
VirtualAlloc
=>仮想メモリに直接割り当て、ブロック単位で予約/コミットします。これは、大規模なアレイなどの大規模な割り当てに最適です。
HeapAlloc
/ new
=>デフォルトのヒープ(または作成できる他のヒープ)にメモリを割り当てます。これはオブジェクトごとに割り当てられ、小さなオブジェクトに最適です。デフォルトのヒープはシリアライズ可能であるため、スレッドの割り当てが保証されています(これにより、高性能シナリオで問題が発生する可能性があるため、独自のヒープを作成できます)。
malloc
=> Cランタイムヒープを使用しますHeapAlloc
が、互換性シナリオでは一般的です。
簡単に言うと、ヒープは、(生の仮想メモリではなく)ヒープマネージャによって管理される仮想メモリのチャンクにすぎません。
メモリワールドの最後のモデルはメモリマップトファイルです。このシナリオは、大量のデータ(大きなファイルなど)に最適です。これは、EXEを開くときに内部的に使用されます(EXEをメモリにロードせず、メモリマップトファイルを作成するだけです)。