RtlCreateHeap, fonction (ntifs.h)
La routine RtlCreateHeap crée un objet tas qui peut être utilisé par le processus appelant. Cette routine réserve de l’espace d’adressage virtuel du processus et alloue un stockage physique pour une partie initiale spécifiée de ce bloc.
Syntaxe
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
);
Paramètres
[in] Flags
Indicateurs spécifiant des attributs facultatifs du tas. Ces options affectent l’accès ultérieur au nouveau tas via des appels aux fonctions de tas (RtlAllocateHeap et RtlFreeHeap).
Les appelants doivent définir ce paramètre sur zéro si aucun attribut facultatif n’est demandé.
Ce paramètre peut être une ou plusieurs des valeurs suivantes.
Valeur | Signification |
---|---|
HEAP_GENERATE_EXCEPTIONS | Spécifie que le système indiquera une défaillance de tas en générant une exception, telle que STATUS_NO_MEMORY, au lieu de retourner NULL. |
HEAP_GROWABLE | Spécifie que le tas est extensible. Doit être spécifié si heapBase a la valeur NULL. |
HEAP_NO_SERIALIZE | Spécifie que l’exclusion mutuelle ne sera pas utilisée lorsque les fonctions de tas allouent et libèrent de la mémoire de ce tas. La valeur par défaut, lorsque HEAP_NO_SERIALIZE n’est pas spécifiée, consiste à sérialiser l’accès au tas. La sérialisation de l’accès au tas permet à deux threads ou plus d’allouer et de libérer de la mémoire à partir du même tas. |
[in, optional] HeapBase
Spécifie l’une des deux actions suivantes :
Si HeapBase est une valeur non NULL, elle spécifie l’adresse de base d’un bloc de mémoire allouée à l’appelant à utiliser pour le tas.
Si heapBase a la valeur NULL, RtlCreateHeap alloue la mémoire système pour le tas à partir de l’espace d’adressage virtuel du processus.
[in, optional] ReserveSize
Si ReserveSize est une valeur différente de zéro, elle spécifie la quantité initiale de mémoire, en octets, à réserver pour le tas. RtlCreateHeap arrondit ReserveSize jusqu’à la limite de page suivante, puis réserve un bloc de cette taille pour le tas.
Ce paramètre est facultatif et peut être égal à zéro. Le tableau suivant résume l’interaction des paramètres ReserveSize et CommitSize.
Valeurs | Résultat |
---|---|
ReserveSize zéro, CommitSize zéro | 64 pages sont initialement réservées au tas. Une page est initialement validée. |
ReserveSize zéro, CommitSize non zéro | RtlCreateHeap définit ReserveSize être égal à CommitSize, puis arrondit ReserveSize jusqu’au multiple le plus proche de (PAGE_SIZE * 16). |
ReserveSize non zéro, CommitSize zéro | Une page est initialement validée pour le tas. |
ReserveSize non zéro, CommitSize non zéro | Si CommitSize est supérieur à ReserveSize, RtlCreateHeap réduit CommitSize à ReserveSize. |
[in, optional] CommitSize
Si CommitSize est une valeur différente de zéro, elle spécifie la quantité initiale de mémoire, en octets, à valider pour le tas. RtlCreateHeap arrondit CommitSize jusqu’à la limite de page suivante, puis valide un bloc de cette taille dans l’espace d’adressage virtuel du processus pour le tas.
Ce paramètre est facultatif et peut être égal à zéro.
[in, optional] Lock
Pointeur vers une structure ERESOURCE opaque à utiliser comme verrou de ressource. Ce paramètre est facultatif et peut être NULL. Lorsqu’elle est fournie par l’appelant, la structure doit être allouée à partir d’un pool non paginé et initialisée en appelant ExInitializeResourceLite ou ExReinitializeResourceLite. Si l’indicateur HEAP_NO_SERIALIZE est défini, ce paramètre doit être NULL.
[in, optional] Parameters
Pointeur vers une structure RTL_HEAP_PARAMETERS qui contient des paramètres à appliquer lors de la création du tas. Ce paramètre est facultatif et peut être NULL.
Valeur de retour
RtlCreateHeap retourne un handle à utiliser pour accéder au tas créé.
Remarques
RtlCreateHeap crée un objet de tas privé à partir duquel le processus appelant peut allouer des blocs de mémoire en appelant RtlAllocateHeap. La taille de validation initiale détermine le nombre de pages qui sont initialement allouées pour le tas. La taille de réserve initiale détermine le nombre de pages initialement réservées au tas. Les pages réservées mais non validées créent un bloc dans l’espace d’adressage virtuel du processus dans lequel le tas peut se développer.
Si les demandes d’allocation effectuées par RtlAllocateHeap dépassent la taille de validation initiale du tas, le système valide des pages supplémentaires de stockage physique pour le tas, jusqu’à la taille maximale du tas. Si le tas n’est pasrowable, sa taille maximale est limitée à sa taille de réserve initiale.
Si le tas est extensible, sa taille est limitée uniquement par la mémoire disponible. Si les demandes par RtlAllocateHeap dépassent la taille actuelle des pages validées, le système appelle ZwAllocateVirtualMemory pour obtenir la mémoire nécessaire, en supposant que le stockage physique est disponible.
En outre, si le tas n’est pas extensible, une limitation absolue survient : la taille maximale d’un bloc de mémoire dans le tas est 0x7F000 octets. Le seuil de mémoire virtuelle du tas est égal à la taille maximale du bloc de tas ou à la valeur du membre
Si le tas est extensible, les demandes d’allocation de blocs supérieurs au seuil de mémoire virtuelle du tas ne échouent pas automatiquement ; le système appelle ZwAllocateVirtualMemory pour obtenir la mémoire nécessaire pour ces blocs volumineux.
La mémoire d’un objet tas privé est accessible uniquement au processus qui l’a créé.
Le système utilise la mémoire du tas privé pour stocker les structures de prise en charge du tas, de sorte que la taille du tas spécifiée n’est pas disponible pour le processus. Par exemple, si RtlAllocateHeap demande 64 kilo-octets (K) à partir d’un tas dont la taille maximale est de 64 Ko, la requête peut échouer en raison de la surcharge système.
Si HEAP_NO_SERIALIZE n’est pas spécifié (valeur par défaut simple), le tas sérialise l’accès au sein du processus appelant. La sérialisation garantit l’exclusion mutuelle lorsque deux threads ou plus tentent d’allouer ou de libérer simultanément des blocs à partir du même tas. Il existe un coût de performances réduit pour la sérialisation, mais il doit être utilisé chaque fois que plusieurs threads allouent et libèrent de la mémoire à partir du même tas.
Définir HEAP_NO_SERIALIZE élimine l’exclusion mutuelle sur le tas. Sans sérialisation, deux threads ou plus qui utilisent le même handle de tas peuvent tenter d’allouer ou de libérer de la mémoire simultanément, ce qui entraîne probablement une altération dans le tas. Par conséquent, HEAP_NO_SERIALIZE ne peut être utilisé en toute sécurité que dans les situations suivantes :
Le processus n’a qu’un seul thread.
Le processus a plusieurs threads, mais un seul thread appelle les fonctions de tas pour un tas spécifique.
Le processus a plusieurs threads et l’application fournit son propre mécanisme d’exclusion mutuelle à un tas spécifique.
Note
Pour vous protéger contre une violation d’accès, utilisez la gestion des exceptions structurées pour protéger tout code qui écrit ou lit à partir d’un tas. Pour plus d’informations sur la gestion des exceptions structurées avec les accès en mémoire, consultez Gestion des exceptions**.
Exigences
Exigence | Valeur |
---|---|
client minimum pris en charge | Windows XP |
plateforme cible | Universel |
d’en-tête | ntifs.h (include Ntifs.h) |
bibliothèque | Ntoskrnl.lib |
DLL | NtosKrnl.exe (mode noyau) ; Ntdll.dll (mode utilisateur) |
IRQL | < DISPATCH_LEVEL |