次の方法で共有


RtlCreateHeap 関数 (ntifs.h)

RtlCreateHeap ルーチンは、呼び出し元のプロセスで使用できるヒープ オブジェクトを作成します。 このルーチンは、プロセスの仮想アドレス空間内の領域を予約し、このブロックの指定された初期部分に物理記憶域を割り当てます。

構文

NTSYSAPI PVOID RtlCreateHeap(
  [in]           ULONG                Flags,
  [in, optional] PVOID                HeapBase,
  [in, optional] SIZE_T               ReserveSize,
  [in, optional] SIZE_T               CommitSize,
  [in, optional] PVOID                Lock,
  [in, optional] PRTL_HEAP_PARAMETERS Parameters
);

パラメーター

[in] Flags

ヒープの省略可能な属性を指定するフラグ。 これらのオプションは、ヒープ関数 (RtlAllocateHeap と RtlFreeHeap) の呼び出しを通じて、以降の新しいヒープへのアクセスに影響します。

省略可能な属性が要求されない場合、呼び出し元はこのパラメーターを 0 に設定する必要があります。

このパラメーターには、次の値のうち 1 つ以上を指定できます。

価値 意味
HEAP_GENERATE_EXCEPTIONS NULL を返す代わりに、STATUS_NO_MEMORYなどの例外を発生させることによって、システムがヒープエラーを示すように指定します。
HEAP_GROWABLE ヒープが拡張可能であることを指定します。 HeapBase NULL の場合は、指定する必要があります。
HEAP_NO_SERIALIZE ヒープ関数が割り当て、このヒープからメモリを解放するときに、相互除外を使用しないことを指定します。 既定では、HEAP_NO_SERIALIZEが指定されていない場合は、ヒープへのアクセスをシリアル化します。 ヒープ アクセスのシリアル化により、2 つ以上のスレッドが同じヒープからメモリを同時に割り当てて解放できます。

[in, optional] HeapBase

次の 2 つのアクションのいずれかを指定します。

heapBase NULL 以外の値の場合は、ヒープに使用する呼び出し元割り当てメモリのブロックのベース アドレスを指定します。

HeapBase が NULL の場合、RtlCreateHeap プロセスの仮想アドレス空間からヒープのシステム メモリを割り当てます。

[in, optional] ReserveSize

ReserveSize が 0 以外の値の場合は、ヒープ用に予約するメモリの初期量 (バイト単位) を指定します。 RtlCreateHeap ReserveSize を次のページ境界に切り上げ、そのサイズのブロックをヒープ用に予約します。

このパラメーターは省略可能で、0 にすることができます。 次の表は、ReserveSize パラメーターと CommitSize パラメーター の相互作用をまとめたものです。

価値観 結果
ReserveSize 0、CommitSize 0 最初は、ヒープ用に 64 ページが予約されています。 1 つのページが最初にコミットされます。
ReserveSize 0、CommitSize 0 以外 RtlCreateHeap 、ReserveSize を CommitSizeに設定し、ReserveSize を最も近い倍数 (PAGE_SIZE * 16) に丸めます。
ReserveSize 0 以外 、CommitSize 0 最初は、ヒープに対して 1 つのページがコミットされます。
ReserveSize 0 以外、CommitSize 0 以外 CommitSize ReserveSizeより大きい場合、RtlCreateHeap により、CommitSize が ReserveSize削減されます。

[in, optional] CommitSize

CommitSize が 0 以外の値の場合は、ヒープに対してコミットするメモリの初期量 (バイト単位) を指定します。 RtlCreateHeap 、CommitSize 次のページ境界まで丸め、そのサイズのブロックをプロセスの仮想アドレス空間でヒープにコミットします。

このパラメーターは省略可能で、0 にすることができます。

[in, optional] Lock

リソース ロックとして使用される不透明な ERESOURCE 構造体へのポインター。 このパラメーターは省略可能であり、NULL にすることができます。 呼び出し元が指定する場合、構造体は非ページ プールから割り当て、ExInitializeResourceLite または ExReinitializeResourceLite呼び出して初期化する必要があります。 HEAP_NO_SERIALIZE フラグが設定されている場合、このパラメーターは NULL である必要があります。

[in, optional] Parameters

ヒープの作成時に適用するパラメーターを含む RTL_HEAP_PARAMETERS 構造体へのポインター。 このパラメーターは省略可能であり、NULL にすることができます。

戻り値

RtlCreateHeap は、作成されたヒープへのアクセスに使用するハンドルを返します。

備考

RtlCreateHeap は、RtlAllocateHeapを呼び出すことによって、呼び出し元プロセスがメモリ ブロック 割り当てることができるプライベート ヒープ オブジェクトを作成します。 初期コミット サイズによって、ヒープに最初に割り当てられたページの数が決まります。 初期予約サイズによって、ヒープ用に最初に予約されたページの数が決まります。 予約されているがコミットされていないページは、ヒープを拡張できるプロセスの仮想アドレス空間にブロックを作成します。

RtlAllocateHeap によって行われた割り当て要求 ヒープの初期コミット サイズを超えた場合、システムはヒープの物理ストレージの追加ページをヒープの最大サイズまでコミットします。 ヒープが拡張できない場合、その最大サイズは初期予約サイズに制限されます。

ヒープが拡張可能な場合、そのサイズは使用可能なメモリによってのみ制限されます。 RtlAllocateHeap 要求 コミット済みページの現在のサイズを超える場合、システムは ZwAllocateVirtualMemory を呼び出して、必要なメモリを取得します (物理ストレージが使用可能であると想定)。

さらに、ヒープが拡張できない場合は、絶対制限が発生します。ヒープ内のメモリ ブロックの最大サイズは0x7F000 バイトです。 ヒープの仮想メモリしきい値は、最大ヒープ ブロック サイズ、または Parameters 構造体の VirtualMemoryThreshold メンバーの値のいずれか小さい方に等しくなります。 また、ヒープはメタデータとアラインメントの目的で要求サイズを埋め込む必要があるため、VirtualMemoryThreshold の 4096 バイト (1 ページ) 以内にブロックを割り当てる要求は、ヒープの最大サイズがブロックを格納するのに十分な大きさであっても失敗する可能性があります。 (VirtualMemoryThresholdの詳細については、RtlCreateHeapを する Parameters パラメーターのメンバーを参照してください)。

ヒープが拡張可能な場合、ヒープの仮想メモリしきい値より大きいブロックを割り当てる要求は自動的に失敗しません。システムは ZwAllocateVirtualMemory 呼び出して、このような大きなブロックに必要なメモリを取得します。

プライベート ヒープ オブジェクトのメモリには、それを作成したプロセスのみがアクセスできます。

システムはプライベート ヒープのメモリを使用してヒープ サポート構造を格納するため、指定したヒープ サイズの一部をプロセスで使用できるわけではありません。 たとえば、RtlAllocateHeap が最大サイズ 64K のヒープから 64 KB (K) を要求した場合、システム オーバーヘッドが原因で要求が失敗する可能性があります。

HEAP_NO_SERIALIZEが指定されていない場合 (単純な既定値)、ヒープは呼び出し元のプロセス内でアクセスをシリアル化します。 シリアル化により、2 つ以上のスレッドが同じヒープからブロックを同時に割り当てまたは解放しようとしたときに、相互の除外が保証されます。 シリアル化にはパフォーマンス コストは小さくなりますが、複数のスレッドが同じヒープからメモリを割り当てて解放するたびに使用する必要があります。

HEAP_NO_SERIALIZEを設定すると、ヒープ上の相互除外が不要になります。 シリアル化を使用しない場合、同じヒープ ハンドルを使用する 2 つ以上のスレッドが同時にメモリの割り当てまたは解放を試み、ヒープの破損を引き起こす可能性があります。 したがって、HEAP_NO_SERIALIZEは、次の状況でのみ安全に使用できます。

  • プロセスにはスレッドが 1 つだけ含まれます。

  • プロセスには複数のスレッドがありますが、特定のヒープのヒープ関数を呼び出すスレッドは 1 つだけです。

  • プロセスには複数のスレッドがあり、アプリケーションは特定のヒープに対して相互に除外するための独自のメカニズムを提供します。

手記

アクセス違反から保護するには、構造化例外処理を使用して、ヒープへの書き込みまたはヒープからの読み取りを行うコードを保護します。 メモリ アクセスを使用した構造化例外処理の詳細については、「例外の処理」を参照してください。

必要条件

要件 価値
サポートされる最小クライアント Windows XP
ターゲット プラットフォーム の 万国
ヘッダー ntifs.h (Ntifs.h を含む)
ライブラリ Ntoskrnl.lib
DLL NtosKrnl.exe (カーネル モード);Ntdll.dll (ユーザー モード)
IRQL < DISPATCH_LEVEL

関連項目

RtlAllocateHeap を する

RtlDestroyHeap を する

RtlFreeHeap を する