Heap Allocation Example

This document provides a practical example of heap allocation in Windows programming, demonstrating how to dynamically allocate and deallocate memory using the heap functions.

Introduction to Heap Allocation

Heap allocation is a fundamental memory management technique where memory is requested from the operating system at runtime. This is in contrast to stack allocation, where memory is automatically managed for local variables within function scopes. Heap allocation is essential for managing data structures whose size is not known at compile time or that need to persist beyond the scope of a function.

Key Functions:

Code Example

The following C++ code demonstrates how to create a heap, allocate memory for an array of integers, use that memory, and then free it.

C++ Code
#include <windows.h>
#include <iostream>

int main() {
    HANDLE hHeap = NULL;
    int* pData = NULL;
    const size_t NUM_ELEMENTS = 10;
    const size_t ELEMENT_SIZE = sizeof( int );
    const size_t ALLOCATION_SIZE = NUM_ELEMENTS * ELEMENT_SIZE;

    // 1. Create a new heap
    hHeap = HeapCreate( 0, ALLOCATION_SIZE, 0 );
    if ( hHeap == NULL ) {
        std::cerr << "Error creating heap: " << GetLastError() << std::endl;
        return 1;
    }
    std::cout << "Heap created successfully." << std::endl;

    // 2. Allocate memory from the heap
    pData = (int*) HeapAlloc( hHeap, 0, ALLOCATION_SIZE );
    if ( pData == NULL ) {
        std::cerr << "Error allocating memory from heap: " << GetLastError() << std::endl;
        HeapDestroy( hHeap ); // Clean up heap if allocation fails
        return 1;
    }
    std::cout << "Memory allocated successfully." << std::endl;

    // 3. Use the allocated memory
    std::cout << "Initializing allocated memory..." << std::endl;
    for ( size_t i = 0; i < NUM_ELEMENTS; ++i ) {
        pData[i] = i * 10;
        std::cout << "pData[" << i << "] = " << pData[i] << std::endl;
    }

    // 4. Free the allocated memory
    if ( HeapFree( hHeap, 0, pData ) == 0 ) {
        std::cerr << "Error freeing memory: " << GetLastError() << std::endl;
        HeapDestroy( hHeap );
        return 1;
    }
    std::cout << "Memory freed successfully." << std::endl;
    pData = NULL; // Good practice to NULL the pointer after freeing

    // 5. Destroy the heap
    if ( HeapDestroy( hHeap ) == 0 ) {
        std::cerr << "Error destroying heap: " << GetLastError() << std::endl;
        return 1;
    }
    std::cout << "Heap destroyed successfully." << std::endl;

    return 0;
}

Explanation

  1. HeapCreate: This function creates a new heap object. The parameters specify flags, initial size, and maximum size. In this example, we provide a reasonable initial size for our expected allocation.
  2. HeapAlloc: This function allocates a specified number of bytes from the heap. It returns a pointer to the allocated memory block or NULL if the allocation fails.
  3. Using Memory: Once memory is allocated, it can be accessed and modified like any other pointer-based data.
  4. HeapFree: This function deallocates a memory block previously allocated with HeapAlloc. It's crucial to free memory when it's no longer needed to prevent memory leaks.
  5. HeapDestroy: This function destroys the heap object, freeing all memory that is still allocated within it. It should be called when the heap is no longer required.

Output Example

When the above code is compiled and executed, the expected output would be similar to this:

Heap created successfully.
Memory allocated successfully.
Initializing allocated memory...
pData[0] = 0
pData[1] = 10
pData[2] = 20
pData[3] = 30
pData[4] = 40
pData[5] = 50
pData[6] = 60
pData[7] = 70
pData[8] = 80
pData[9] = 90
Memory freed successfully.
Heap destroyed successfully.

Important Considerations