VirtualAlloc-Funktion (memoryapi.h)

Reserviert, committet oder ändert den Zustand einer Region von Seiten im virtuellen Adressraum des aufrufenden Prozesses. Der von dieser Funktion zugeordnete Arbeitsspeicher wird automatisch mit 0 (null) initialisiert.

Um Arbeitsspeicher im Adressraum eines anderen Prozesses zuzuweisen, verwenden Sie die VirtualAllocEx-Funktion .

Syntax

LPVOID VirtualAlloc(
  [in, optional] LPVOID lpAddress,
  [in]           SIZE_T dwSize,
  [in]           DWORD  flAllocationType,
  [in]           DWORD  flProtect
);

Parameter

[in, optional] lpAddress

Die Startadresse der zuzuordnenden Region. Wenn der Arbeitsspeicher reserviert wird, wird die angegebene Adresse auf das nächste Vielfache der Zuordnungsgranularität gerundet. Wenn der Arbeitsspeicher bereits reserviert ist und ein Commit ausgeführt wird, wird die Adresse auf die nächste Seitengrenze gerundet. Verwenden Sie die GetSystemInfo-Funktion , um die Größe einer Seite und die Zuordnungsgranularität auf dem Hostcomputer zu bestimmen. Wenn dieser Parameter NULL ist, bestimmt das System, wo die Region zugeordnet werden soll.

Wenn sich diese Adresse innerhalb einer Enclave befindet, die Sie nicht durch Aufrufen von InitializeEnclave initialisiert haben, weist VirtualAlloc eine Seite mit Nullen für die Enclave an dieser Adresse zu. Die Seite muss zuvor nicht festgelegt sein und wird nicht mit der EEXTEND-Anweisung des Intel Software Guard Extensions-Programmiermodells gemessen.

Wenn sich die Adresse innerhalb einer Enclave befindet, die Sie initialisiert haben, schlägt der Zuordnungsvorgang mit dem ERROR_INVALID_ADDRESS Fehler fehl. Dies gilt für Enclaves, die keine dynamische Speicherverwaltung unterstützen (z. B. SGX1). SGX2-Enclaves erlauben die Zuordnung, und die Seite muss von der Enclave akzeptiert werden, nachdem sie zugewiesen wurde.

[in] dwSize

Die Größe des Bereichs in Bytes. Wenn der lpAddress-ParameterNULL ist, wird dieser Wert auf die nächste Seitengrenze aufgerundet. Andernfalls enthalten die zugeordneten Seiten alle Seiten, die ein oder mehrere Bytes im Bereich von lpAddress bis lpAddress+dwSize enthalten. Dies bedeutet, dass ein 2-Byte-Bereich, der eine Seitengrenze überspannt, dazu führt, dass beide Seiten in den zugeordneten Bereich eingeschlossen werden.

[in] flAllocationType

Der Typ der Speicherbelegung. Dieser Parameter muss einen der folgenden Werte enthalten.

Wert Bedeutung
MEM_COMMIT
0x00001000
Ordnet Arbeitsspeichergebühren (aus der Gesamtgröße des Arbeitsspeichers und den Auslagerungsdateien auf dem Datenträger) für die angegebenen reservierten Speicherseiten zu. Die Funktion garantiert auch, dass der Inhalt null ist, wenn der Aufrufer später zunächst auf den Speicher zugreift. Tatsächliche physische Seiten werden nur zugeordnet, wenn/bis auf die virtuellen Adressen tatsächlich zugegriffen wird.

Um Seiten in einem Schritt zu reservieren und zu committen, rufen Sie VirtualAlloc mit MEM_COMMIT | MEM_RESERVEauf.

Der Versuch, einen bestimmten Adressbereich durch Angabe von MEM_COMMIT ohne MEM_RESERVE und eine lpAddress ungleich NULL zu committen, schlägt fehl, es sei denn, der gesamte Bereich wurde bereits reserviert. Der resultierende Fehlercode ist ERROR_INVALID_ADDRESS.

Ein Commit für eine Seite, die bereits committet wurde, führt nicht dazu, dass die Funktion fehlschlägt. Dies bedeutet, dass Sie Seiten committen können, ohne zuerst den aktuellen Verpflichtungsstatus jeder Seite zu ermitteln.

Wenn lpAddress eine Adresse innerhalb einer Enclave angibt, muss flAllocationTypeMEM_COMMIT sein.

MEM_RESERVE
0x00002000
Reserviert einen Bereich des virtuellen Adressraums des Prozesses, ohne den tatsächlichen physischen Speicher im Arbeitsspeicher oder in der Auslagerungsdatei auf dem Datenträger zuzuweisen.

Sie können reservierte Seiten in nachfolgenden Aufrufen der VirtualAlloc-Funktion committen. Um Seiten in einem Schritt zu reservieren und zu committen, rufen Sie VirtualAlloc mit MEM_COMMIT | MEM_RESERVE auf.

Andere Speicherbelegungsfunktionen wie malloc und LocalAlloc können einen reservierten Speicherbereich erst verwenden, wenn er freigegeben wird.

MEM_RESET
0x00080000
Gibt an, dass Daten im von lpAddress und dwSize angegebenen Speicherbereich nicht mehr von Interesse sind. Die Seiten sollten nicht aus der Auslagerungsdatei gelesen oder in diese geschrieben werden. Der Speicherblock wird jedoch später wieder verwendet, sodass er nicht decommittediert werden sollte. Dieser Wert kann nicht mit anderen Werten verwendet werden.

Die Verwendung dieses Werts garantiert nicht, dass der mit MEM_RESET betriebene Bereich Nullen enthält. Wenn der Bereich Nullen enthalten soll, heben Sie den Arbeitsspeicher auf, und fügen Sie ihn dann erneut hinzu.

Wenn Sie MEM_RESET angeben, ignoriert die VirtualAlloc-Funktion den Wert von flProtect. Sie müssen flProtect jedoch trotzdem auf einen gültigen Schutzwert festlegen, z. B. PAGE_NOACCESS.

VirtualAlloc gibt einen Fehler zurück, wenn Sie MEM_RESET verwenden und der Speicherbereich einer Datei zugeordnet ist. Eine freigegebene Ansicht ist nur zulässig, wenn sie einer Auslagerungsdatei zugeordnet ist.

MEM_RESET_UNDO
0x1000000
MEM_RESET_UNDO sollte nur für einen Adressbereich aufgerufen werden, auf den MEM_RESET zuvor erfolgreich angewendet wurde. Es gibt an, dass die Daten im angegebenen Speicherbereich, die von lpAddress und dwSize angegeben werden, für den Aufrufer von Interesse sind und versucht, die Auswirkungen der MEM_RESET umzukehren. Wenn die Funktion erfolgreich ist, bedeutet dies, dass alle Daten im angegebenen Adressbereich intakt sind. Wenn die Funktion fehlschlägt, wurden zumindest einige der Daten im Adressbereich durch Nullen ersetzt.

Dieser Wert kann nicht mit anderen Werten verwendet werden. Wenn MEM_RESET_UNDO für einen Adressbereich aufgerufen wird, der zuvor nicht MEM_RESET war, ist das Verhalten nicht definiert. Wenn Sie MEM_RESET angeben, ignoriert die VirtualAlloc-Funktion den Wert von flProtect. Sie müssen flProtect jedoch trotzdem auf einen gültigen Schutzwert festlegen, z. B. PAGE_NOACCESS.

Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 und Windows XP: Das MEM_RESET_UNDO-Flag wird erst unterstützt, wenn Windows 8 und Windows Server 2012.

Dieser Parameter kann auch die folgenden Werte angeben, wie angegeben.

Wert Bedeutung
MEM_LARGE_PAGES
0x20000000
Ordnet Arbeitsspeicher mithilfe von Unterstützung für große Seiten zu.

Größe und Ausrichtung müssen ein Vielfaches des großformatigen Minimums sein. Verwenden Sie zum Abrufen dieses Werts die GetLargePageMinimum-Funktion .

Wenn Sie diesen Wert angeben, müssen Sie auch MEM_RESERVE und MEM_COMMIT angeben.

MEM_PHYSICAL
0x00400000
Reserviert einen Adressbereich, der zum Zuordnen von AWE-Seiten ( Address Windowing Extensions ) verwendet werden kann.

Dieser Wert muss mit MEM_RESERVE und keinem anderen Wert verwendet werden.

MEM_TOP_DOWN
0x00100000
Ordnet Arbeitsspeicher mit der höchstmöglichen Adresse zu. Dies kann langsamer sein als reguläre Zuordnungen, insbesondere wenn viele Zuordnungen vorhanden sind.
MEM_WRITE_WATCH
0x00200000
Bewirkt, dass das System Seiten nachverfolgt, die in der zugeordneten Region geschrieben werden. Wenn Sie diesen Wert angeben, müssen Sie auch MEM_RESERVE angeben.

Rufen Sie die GetWriteWatch-Funktion auf, um die Adressen der Seiten abzurufen, die seit der Zuordnung der Region geschrieben wurden oder der Schreibnachverfolgungsstatus zurückgesetzt wurde. Um den Schreibnachverfolgungsstatus zurückzusetzen, rufen Sie GetWriteWatch oder ResetWriteWatch auf. Die Schreibnachverfolgungsfunktion bleibt für den Speicherbereich aktiviert, bis die Region freigegeben wird.

[in] flProtect

Der Speicherschutz für den Bereich der zuzuordnenden Seiten. Wenn für die Seiten ein Commit ausgeführt wird, können Sie eine beliebige der Speicherschutzkonstanten angeben.

Wenn lpAddress eine Adresse innerhalb einer Enclave angibt, darf flProtect keiner der folgenden Werte sein:

  • PAGE_NOACCESS
  • PAGE_GUARD
  • PAGE_NOCACHE
  • PAGE_WRITECOMBINE

Bei der Zuweisung von dynamischem Arbeitsspeicher für eine Enclave muss der flProtect-ParameterPAGE_READWRITE oder PAGE_EXECUTE_READWRITE sein.

Rückgabewert

Wenn die Funktion erfolgreich ist, ist der Rückgabewert die Basisadresse des zugeordneten Bereichs der Seiten.

Wenn bei der Funktion ein Fehler auftritt, ist der Rückgabewert NULL. Um erweiterte Fehlerinformationen zu erhalten, rufen Sie GetLastError auf.

Hinweise

Jede Seite hat einen zugeordneten Seitenzustand. Die VirtualAlloc-Funktion kann die folgenden Vorgänge ausführen:

  • Commit für eine Region mit reservierten Seiten
  • Reservieren einer Region mit kostenlosen Seiten
  • Gleichzeitige Reservierung und Commit für eine Region mit kostenlosen Seiten

VirtualAlloc kann keine reservierte Seite reservieren. Es kann eine Seite committen, die bereits committet wurde. Dies bedeutet, dass Sie einen Bereich von Seiten committen können, unabhängig davon, ob sie bereits committet wurden, und die Funktion nicht fehlschlägt.

Sie können VirtualAlloc verwenden, um einen Block von Seiten zu reservieren und dann zusätzliche Aufrufe an VirtualAlloc vorzunehmen, um einzelne Seiten aus dem reservierten Block zu binden. Dadurch kann ein Prozess einen Bereich des virtuellen Adressraums reservieren, ohne physischen Speicher zu verwenden, bis er benötigt wird.

Wenn der lpAddress-Parameter nicht NULL ist, verwendet die Funktion die Parameter lpAddress und dwSize , um den Bereich der zuzuordnenden Seiten zu berechnen. Der aktuelle Zustand des gesamten Seitenbereichs muss mit dem Vom flAllocationType-Parameter angegebenen Zuordnungstyp kompatibel sein. Andernfalls schlägt die Funktion fehl, und keine der Seiten wird zugeordnet. Diese Kompatibilitätsanforderung schließt das Commit einer bereits zugesagten Seite nicht aus, wie bereits erwähnt.

Um dynamisch generierten Code auszuführen, verwenden Sie VirtualAlloc , um Arbeitsspeicher zuzuweisen, und die VirtualProtect-Funktion , um PAGE_EXECUTE Zugriff zu gewähren.

Die VirtualAlloc-Funktion kann verwendet werden, um eine AWE-Speicherregion ( Address Windowing Extensions ) im virtuellen Adressraum eines angegebenen Prozesses zu reservieren. Dieser Bereich des Arbeitsspeichers kann dann verwendet werden, um physische Seiten nach Bedarf in und aus dem virtuellen Arbeitsspeicher zuzuordnen. Die werte MEM_PHYSICAL und MEM_RESERVE müssen im AllocationType-Parameter festgelegt werden. Der MEM_COMMIT-Wert darf nicht festgelegt werden. Der Seitenschutz muss auf PAGE_READWRITE festgelegt werden.

Die VirtualFree-Funktion kann eine committete Seite aufheben, den Speicher der Seite freigeben oder gleichzeitig die Einstellung aufheben und eine committe Seite freigeben. Es kann auch eine reservierte Seite freigeben, sodass sie eine kostenlose Seite ist.

Beim Erstellen einer region, die ausführbar ist, trägt das aufrufende Programm die Verantwortung für die Sicherstellung der Cachekohärenz über einen entsprechenden Aufruf von FlushInstructionCache , sobald der Code festgelegt wurde. Andernfalls können Versuche, Code aus der neu ausführbaren Region auszuführen, zu unvorhersehbaren Ergebnissen führen.

Beispiele

Ein Beispiel finden Sie unter Reservieren und Commiten von Arbeitsspeicher.

Anforderungen

   
Unterstützte Mindestversion (Client) Windows XP [Desktop-Apps | UWP-Apps]
Unterstützte Mindestversion (Server) Windows Server 2003 [Desktop-Apps | UWP-Apps]
Zielplattform Windows
Kopfzeile memoryapi.h (einschließlich Windows.h, Memoryapi.h)
Bibliothek onecore.lib
DLL Kernel32.dll

Siehe auch

Speicherverwaltungsfunktionen

Funktionen des virtuellen Speichers

VirtualAllocEx

VirtualFree

VirtualLock

VirtualProtect

Virtualquery

In VBS-Enklaven verfügbare Vertdll-APIs