VirtualAlloc-Funktion (memoryapi.h)
Reserviert, commits oder ändert den Status eines Seitenbereichs im virtuellen Adressraum des aufrufenden Prozesses. Der von dieser Funktion zugewiesene Arbeitsspeicher wird automatisch auf Null initialisiert.
Verwenden Sie die VirtualAllocEx--Funktion, um Speicher im Adressraum eines anderen Prozesses zuzuweisen.
Syntax
LPVOID VirtualAlloc(
[in, optional] LPVOID lpAddress,
[in] SIZE_T dwSize,
[in] DWORD flAllocationType,
[in] DWORD flProtect
);
Parameter
[in, optional] lpAddress
Die Startadresse der Region, die zugewiesen werden soll. Wenn der Speicher reserviert wird, wird die angegebene Adresse auf das nächste Vielfache der Zuordnungs granularität aufgerundet. Wenn der Speicher bereits reserviert ist und ein Commit ausgeführt wird, wird die Adresse auf die nächste Seitengrenze abgerundet. Um die Größe einer Seite und die Zuordnungs granularität auf dem Hostcomputer zu bestimmen, verwenden Sie die GetSystemInfo--Funktion. Wenn dieser Parameter NULL-ist, bestimmt das System, wo die Region zugeordnet werden soll.
Wenn sich diese Adresse in einer Enklave befindet, die Sie nicht initialisiert haben, indem Sie InitializeEnklaveaufrufen, VirtualAlloc eine Seite mit Nullen für die Enklave an dieser Adresse zuweist. Die Seite muss zuvor nicht ausgelassen werden und wird nicht mit der EEXTEND-Anweisung des Intel Software Guard Extensions-Programmiermodells gemessen.
Wenn sich die Adresse in einer Enklave befindet, die Sie initialisiert haben, schlägt der Zuordnungsvorgang mit dem ERROR_INVALID_ADDRESS Fehler fehl. Das gilt für Enklaven, die keine dynamische Speicherverwaltung unterstützen (d. h. SGX1). SGX2-Enklaven erlauben die Zuordnung, und die Seite muss von der Enklave akzeptiert werden, nachdem sie zugeteilt wurde.
[in] dwSize
Die Größe des Bereichs in Byte. Wenn der parameter lpAddressNULList, wird dieser Wert auf die nächste Seitengrenze aufgerundet. Andernfalls enthalten die zugeordneten Seiten alle Seiten mit mindestens einem Byte im Bereich von lpAddress bis lpAddress+dwSize. Dies bedeutet, dass ein 2-Byte-Bereich, der eine Seitengrenze überspannt, bewirkt, dass beide Seiten in den zugeordneten Bereich eingeschlossen werden.
[in] flAllocationType
Der Typ der Speicherzuweisung. Dieser Parameter muss einen der folgenden Werte enthalten.
Wert | Bedeutung |
---|---|
|
Weist Speichergebühren (von der Gesamtgröße des Arbeitsspeichers und der Auslagerungsdateien auf dem Datenträger) für die angegebenen reservierten Speicherseiten zu. Die Funktion garantiert außerdem, dass der Inhalt null ist, wenn der Aufrufer zu einem späteren Zeitpunkt auf den Speicher zugreift. Tatsächliche physische Seiten werden nur zugewiesen, wenn/bis tatsächlich auf die virtuellen Adressen zugegriffen wird.
Rufen Sie VirtualAlloc mit Wenn Sie versuchen, einen bestimmten Adressbereich zu übernehmen, indem Sie MEM_COMMIT ohne MEM_RESERVE und eine nichtNULL-lpAddress- angeben, tritt ein Fehler auf, es sei denn, der gesamte Bereich wurde bereits reserviert. Der resultierende Fehlercode ist ERROR_INVALID_ADDRESS. Ein Versuch, eine Seite zu übernehmen, die bereits zugesichert wurde, führt nicht dazu, dass die Funktion fehlschlägt. Dies bedeutet, dass Sie Seiten übernehmen können, ohne zuerst den aktuellen Verpflichtungsstatus jeder Seite zu bestimmen. Wenn lpAddress eine Adresse innerhalb einer Enklave angibt, muss flAllocationType-MEM_COMMITsein. |
|
Reserviert einen Bereich des virtuellen Adressraums des Prozesses, ohne 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 übernehmen. Rufen Sie VirtualAlloc mit MEM_COMMIT | MEM_RESERVEauf, um Seiten in einem Schritt zu reservieren und zu übernehmen. Andere Speicherzuweisungsfunktionen wie malloc und LocalAlloc-können erst dann einen reservierten Speicherbereich verwenden, wenn sie freigegeben wird. |
|
Gibt an, dass Daten im durch lpAddress- angegebenen Speicherbereich und dwSize- nicht mehr interessant sind. Die Seiten sollten nicht aus der Auslagerungsdatei gelesen oder in die Auslagerungsdatei geschrieben werden. Der Speicherblock wird jedoch später wieder verwendet, sodass er nicht mehr ausgelassen werden sollte. Dieser Wert kann nicht mit einem anderen Wert verwendet werden.
Die Verwendung dieses Werts garantiert nicht, dass der mit MEM_RESET betriebene Bereich Nullen enthält. Wenn der Bereich Nullen enthalten soll, dekommitieren Sie den Speicher, und übermitteln Sie ihn dann erneut. Wenn Sie MEM_RESETangeben, ignoriert die funktion VirtualAlloc den Wert flProtect. Sie müssen jedoch weiterhin flProtect- 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 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, der durch lpAddress und dwSize- für den Aufrufer von Interesse ist und versucht, die Auswirkungen von MEM_RESETrückgängig zu machen. Wenn die Funktion erfolgreich ist, bedeutet dies, dass alle Daten im angegebenen Adressbereich intakt sind. Wenn die Funktion fehlschlägt, wurden mindestens einige der Daten im Adressbereich durch Nullen ersetzt.
Dieser Wert kann nicht mit einem anderen Wert verwendet werden. Wenn MEM_RESET_UNDO für einen Adressbereich aufgerufen wird, der zuvor nicht MEM_RESET wurde, ist das Verhalten nicht definiert. Wenn Sie MEM_RESETangeben, ignoriert die funktion VirtualAlloc den Wert flProtect. Sie müssen jedoch weiterhin flProtect- 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 flag MEM_RESET_UNDO wird erst unter Windows 8 und Windows Server 2012 unterstützt. |
Dieser Parameter kann auch die folgenden Werte wie angegeben angeben.
Wert | Bedeutung |
---|---|
|
Ordnet Arbeitsspeicher mithilfe Unterstützung für große Seitenzu.
Die Größe und Ausrichtung müssen ein Vielfaches des Minimums für große Seiten sein. Verwenden Sie zum Abrufen dieses Werts die GetLargePageMinimum-Funktion. Wenn Sie diesen Wert angeben, müssen Sie auch MEM_RESERVE und MEM_COMMITangeben. |
|
Reserviert einen Adressbereich, der verwendet werden kann, um Adressfenstererweiterungen (AWE)-Seiten zuzuordnen.
Dieser Wert muss mit MEM_RESERVE und keinen anderen Werten verwendet werden. |
|
Weist Speicher mit der höchsten möglichen Adresse zu. Dies kann langsamer als die regulären Zuordnungen sein, insbesondere wenn viele Zuordnungen vorhanden sind. |
|
Bewirkt, dass das System Seiten nachverfolgt, die in die zugeordnete Region geschrieben wurden. Wenn Sie diesen Wert angeben, müssen Sie auch MEM_RESERVEangeben.
Rufen Sie die GetWriteWatch-Funktion auf, um die Adressen der Seiten abzurufen, die seit der Zuordnung der Region geschrieben wurden oder der Schreibverfolgungsstatus zurückgesetzt wurde. Rufen Sie GetWriteWatch- oder ResetWriteWatch-auf, um den Schreibstatus zurückzusetzen. Das Feature zum Nachverfolgen von Schreibvorgängen bleibt für den Speicherbereich aktiviert, bis die Region freigegeben wird. |
[in] flProtect
Der Speicherschutz für den Bereich der zuzuordnenden Seiten. Wenn die Seiten zugesichert werden, können Sie eine der Speicherschutzkonstantenangeben.
Wenn lpAddress- eine Adresse innerhalb einer Enklave angibt, kann flProtect keine der folgenden Werte sein:
- PAGE_NOACCESS
- PAGE_GUARD
- PAGE_NOCACHE
- PAGE_WRITECOMBINE
Beim Zuweisen des dynamischen Speichers für eine Enklave muss der parameter flProtectPAGE_READWRITE oder PAGE_EXECUTE_READWRITEsein.
Rückgabewert
Wenn die Funktion erfolgreich ist, ist der Rückgabewert die Basisadresse des zugeordneten Seitenbereichs.
Wenn die Funktion fehlschlägt, ist der Rückgabewert NULL-. Rufen Sie GetLastErrorauf, um erweiterte Fehlerinformationen zu erhalten.
Bemerkungen
Jede Seite verfügt über einen zugeordneten Seitenzustand. Die funktion VirtualAlloc kann die folgenden Vorgänge ausführen:
- Übernehmen eines Bereichs reservierter Seiten
- Reservieren einer Region mit kostenlosen Seiten
- Gleichzeitiges Reservieren und Übernehmen einer Region kostenloser Seiten
VirtualAlloc kann keine reservierte Seite reservieren. Sie kann eine Seite übernehmen, die bereits zugesichert ist. Dies bedeutet, dass Sie einen Seitenbereich übernehmen können, unabhängig davon, ob sie bereits zugesichert wurden, und die Funktion schlägt nicht fehl.
Sie können VirtualAlloc- verwenden, um einen Seitenblock zu reservieren und dann zusätzliche Aufrufe an VirtualAlloc vorzunehmen, um einzelne Seiten aus dem reservierten Block zu übernehmen. Dadurch kann ein Prozess einen Bereich seines virtuellen Adressraums reservieren, ohne physischen Speicher zu verbrauchen, bis er benötigt wird.
Wenn der parameter lpAddress nicht NULList, verwendet die Funktion die lpAddress und dwSize Parameter, um den bereich der zuzuordnenden Seiten zu berechnen. Der aktuelle Zustand des gesamten Seitenbereichs muss mit dem Typ der Zuordnung kompatibel sein, die vom flAllocationType Parameter angegeben wurde. Andernfalls schlägt die Funktion fehl, und keiner der Seiten wird zugewiesen. Diese Kompatibilitätsanforderung schließt das Commit einer bereits zugesicherten Seite nicht aus, wie zuvor erwähnt.
Um dynamisch generierten Code auszuführen, verwenden Sie VirtualAlloc-, um Arbeitsspeicher und die VirtualProtect--Funktion zuzuweisen, um PAGE_EXECUTE Zugriff zu gewähren.
Die VirtualAlloc-Funktion kann verwendet werden, um eine Adressfenstererweiterungen (AWE)-Bereich des Arbeitsspeichers innerhalb des virtuellen Adressraums eines angegebenen Prozesses zu reservieren. Dieser Speicherbereich kann dann verwendet werden, um physische Seiten nach Bedarf der Anwendung in und außerhalb des virtuellen Arbeitsspeichers zuzuordnen. Die werte MEM_PHYSICAL und MEM_RESERVE müssen im parameter AllocationType festgelegt werden. Der wert MEM_COMMIT darf nicht festgelegt werden. Der Seitenschutz muss auf PAGE_READWRITEfestgelegt werden.
Die funktion VirtualFree kann eine zugesicherte Seite aufheben, den Speicher der Seite freigeben oder gleichzeitig eine zugesicherte Seite aufheben und freigeben. Sie kann auch eine reservierte Seite freigeben, wodurch sie eine kostenlose Seite wird.
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, nachdem der Code eingerichtet wurde. Andernfalls kann der Versuch, Code aus dem neu ausführbaren Bereich auszuführen, zu unvorhersehbaren Ergebnissen führen.
Beispiele
Ein Beispiel finden Sie unter Reserving and Commit memory.
Anforderungen
Anforderung | Wert |
---|---|
mindestens unterstützte Client- | Windows XP [Desktop-Apps | UWP-Apps] |
mindestens unterstützte Server- | Windows Server 2003 [Desktop-Apps | UWP-Apps] |
Zielplattform- | Fenster |
Header- | memoryapi.h (include Windows.h, Memoryapi.h) |
Library | onecore.lib |
DLL- | Kernel32.dll |