Énumération d’un tas
L’exemple suivant illustre l’utilisation de la fonction HeapWalk pour énumérer un tas.
Tout d’abord, l’exemple crée un tas privé avec la fonction HeapCreate . Ensuite, il utilise HeapLock pour verrouiller le tas afin que d’autres threads ne puissent pas accéder au tas pendant son énumération. L’exemple appelle ensuite HeapWalk avec un pointeur vers une structure PROCESS_HEAP_ENTRY et itère dans le tas, en imprimant chaque entrée dans la console.
Une fois l’énumération terminée, l’exemple utilise HeapUnlock pour déverrouiller le tas afin que d’autres threads puissent y accéder. Enfin, l’exemple appelle HeapDestroy pour détruire le tas privé.
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
int __cdecl _tmain()
{
DWORD LastError;
HANDLE hHeap;
PROCESS_HEAP_ENTRY Entry;
//
// Create a new heap with default parameters.
//
hHeap = HeapCreate(0, 0, 0);
if (hHeap == NULL) {
_tprintf(TEXT("Failed to create a new heap with LastError %d.\n"),
GetLastError());
return 1;
}
//
// Lock the heap to prevent other threads from accessing the heap
// during enumeration.
//
if (HeapLock(hHeap) == FALSE) {
_tprintf(TEXT("Failed to lock heap with LastError %d.\n"),
GetLastError());
return 1;
}
_tprintf(TEXT("Walking heap %#p...\n\n"), hHeap);
Entry.lpData = NULL;
while (HeapWalk(hHeap, &Entry) != FALSE) {
if ((Entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0) {
_tprintf(TEXT("Allocated block"));
if ((Entry.wFlags & PROCESS_HEAP_ENTRY_MOVEABLE) != 0) {
_tprintf(TEXT(", movable with HANDLE %#p"), Entry.Block.hMem);
}
if ((Entry.wFlags & PROCESS_HEAP_ENTRY_DDESHARE) != 0) {
_tprintf(TEXT(", DDESHARE"));
}
}
else if ((Entry.wFlags & PROCESS_HEAP_REGION) != 0) {
_tprintf(TEXT("Region\n %d bytes committed\n") \
TEXT(" %d bytes uncommitted\n First block address: %#p\n") \
TEXT(" Last block address: %#p\n"),
Entry.Region.dwCommittedSize,
Entry.Region.dwUnCommittedSize,
Entry.Region.lpFirstBlock,
Entry.Region.lpLastBlock);
}
else if ((Entry.wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE) != 0) {
_tprintf(TEXT("Uncommitted range\n"));
}
else {
_tprintf(TEXT("Block\n"));
}
_tprintf(TEXT(" Data portion begins at: %#p\n Size: %d bytes\n") \
TEXT(" Overhead: %d bytes\n Region index: %d\n\n"),
Entry.lpData,
Entry.cbData,
Entry.cbOverhead,
Entry.iRegionIndex);
}
LastError = GetLastError();
if (LastError != ERROR_NO_MORE_ITEMS) {
_tprintf(TEXT("HeapWalk failed with LastError %d.\n"), LastError);
}
//
// Unlock the heap to allow other threads to access the heap after
// enumeration has completed.
//
if (HeapUnlock(hHeap) == FALSE) {
_tprintf(TEXT("Failed to unlock heap with LastError %d.\n"),
GetLastError());
}
//
// When a process terminates, allocated memory is reclaimed by the operating
// system so it is not really necessary to call HeapDestroy in this example.
// However, it may be advisable to call HeapDestroy in a longer running
// application.
//
if (HeapDestroy(hHeap) == FALSE) {
_tprintf(TEXT("Failed to destroy heap with LastError %d.\n"),
GetLastError());
}
return 0;
}
La sortie suivante montre les résultats typiques d’un tas nouvellement créé.
Walking heap 0X00530000...
Region
4096 bytes committed
258048 bytes uncommitted
First block address: 0X00530598
Last block address: 0X00570000
Data portion begins at: 0X00530000
Size: 1416 bytes
Overhead: 0 bytes
Region index: 0
Block
Data portion begins at: 0X005307D8
Size: 2056 bytes
Overhead: 16 bytes
Region index: 0
Uncommitted range
Data portion begins at: 0X00531000
Size: 258048 bytes
Overhead: 0 bytes
Region index: 0
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour