Fonction RtlCreateHeap (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 dans l’espace d’adressage virtuel du processus et alloue du stockage physique à 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 les attributs facultatifs du tas. Ces options affectent l’accès ultérieur au nouveau tas par le biais d’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 prendre une ou plusieurs des valeurs suivantes.

Valeur Signification
HEAP_GENERATE_EXCEPTIONS Spécifie que le système indiquera une défaillance de tas en levant une exception, telle que STATUS_NO_MEMORY, au lieu de retourner NULL.
HEAP_GROWABLE Spécifie que le tas peut être agrandi. 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. Lorsque HEAP_NO_SERIALIZE n’est pas spécifié, la valeur par défaut consiste à sérialiser l’accès au tas. La sérialisation de l’accès au tas permet à deux threads ou plus d’allouer simultanément et de libérer de la mémoire du même tas.

[in, optional] HeapBase

Spécifie l’une des deux actions suivantes :

Si HeapBase est une valeur non NULL, il 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 de 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. RtlCreateHeaparrondit ReserveSize à 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écapitule l’interaction des paramètres ReserveSize et CommitSize .

Valeurs Résultats
ReserveSize zero, CommitSize zero 64 pages sont initialement réservées au tas. Une page est initialement validée.
ReserveSize zero, CommitSize non zéro RtlCreateHeap définit ReserveSize comme étant égal à CommitSize, puis arrondit ReserveSize 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. RtlCreateHeaparrondit CommitSize à 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 sans pagination 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 retournée

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 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 de stockage physique supplémentaires pour le tas, jusqu’à la taille maximale du tas. Si le tas n’est pas extensible, sa taille maximale est limitée à sa taille de réserve initiale.

Si le tas peut croître, sa taille est limitée uniquement par la mémoire disponible. Si les demandes de 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 VirtualMemoryThreshold de la structure Parameters , selon la valeur la moins élevée. Le tas peut également nécessiter un remplissage de la taille de la demande à des fins de métadonnées et d’alignement, de sorte que les demandes d’allocation de blocs dans les 4 096 octets (1 page) de VirtualMemoryThreshold peuvent échouer même si la taille maximale du tas est suffisamment grande pour contenir le bloc. (Pour plus d’informations sur VirtualMemoryThreshold, consultez les membres du paramètre Parameters sur RtlCreateHeap.)

Si le tas est extensible, les demandes d’allocation de blocs supérieurs au seuil de mémoire virtuelle du tas n’é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 toutes les tailles de tas spécifiées ne sont pas disponibles pour le processus. Par exemple, si RtlAllocateHeap demande 64 kilo-octets (K) à partir d’un tas d’une taille maximale de 64 Ko, la demande peut échouer en raison de la surcharge du 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 d’appel. La sérialisation garantit l’exclusion mutuelle lorsque deux ou plusieurs threads tentent d’allouer simultanément ou de libérer des blocs du même tas. La sérialisation coûte peu de performances, mais elle doit être utilisée chaque fois que plusieurs threads allouent et libèrent de la mémoire du même tas.

La définition de 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 risque d’endommager 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 comporte plusieurs threads, mais un seul thread appelle les fonctions de tas pour un tas spécifique.

  • Le processus comporte plusieurs threads, et l’application fournit son propre mécanisme d’exclusion mutuelle à un tas spécifique.

Notes

Pour vous protéger contre une violation d’accès, utilisez la gestion structurée des exceptions pour protéger tout code qui écrit ou lit dans un tas. Pour plus d’informations sur la gestion structurée des exceptions avec accès à la mémoire, consultez Gestion des exceptions**.

Configuration requise

Condition requise Valeur
Client minimal pris en charge Windows XP
Plateforme cible Universal
En-tête ntifs.h (include Ntifs.h)
Bibliothèque Ntoskrnl.lib
DLL NtosKrnl.exe (mode noyau) ; Ntdll.dll (mode utilisateur)
IRQL < DISPATCH_LEVEL

Voir aussi

RtlAllocateHeap

RtlDestroyHeap

RtlFreeHeap