### Example of a Shared a User Heap (Windows)

The following program shows how you might implement a heap shared between a parent process and several child processes. The program consists of two parts. The first part shows the parent process, which creates the shared heap. The second part shows the child process started by a loop in the parent process.

Parent Process

The parent process creates the shared heap.

1. The main program calls the init function to allocate shared memory from the operating system (using CreateFileMapping) and name the memory so that other processes can use it by name.
2. The init function creates and opens the heap.
3. The loop in the main program performs operations on the heap, and also starts other processes.
4. The program calls the term function to close and destroy the heap.

Sharing memory across processes in Windows/NT is accomplished by using Win32 File API's, using the system paging file as the shared file. If you wish to use the C library heap functions, you must also ensure that the memory to be shared is allocated at the same address in all processes which will be sharing the heap.

Child Process

The child process is started by the loop in the parent process.

1. This process uses OpenFileMapping to access the shared memory by name.
2. It extracts the heap handle for the heap created by the parent process.
3. The process opens the heap, makes it the default heap, and performs some operations on it in the loop.
4. After the loop, the process replaces the old default heap, closes the user heap, and ends.

    /* User Heap - Parent Process */

    #include <umalloc.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <windows.h>
    #include <winbase.h>

    #define PAGING_FILE 0xFFFFFFFF
    #define MEMORY_SIZE 65536
    #define BASE_MEM (VOID*)0x01000000

    static HANDLE hFile; /* Handle to memory file */
    static void* hMap; /* Handle to allocated memory */

    typedef struct mem_info {
    void * pBase;
    Heap_t pHeap;
    } MEM_INFO_T;

    /*------------------------------------------------------------------------*/
    /* inithp: */
    /* Function to create and open the heap with a named shared memory object */
    /*------------------------------------------------------------------------*/
    static Heap_t inithp(size_t heap_size)
    {
    MEM_INFO_T info; /* Info structure */

    /* Allocate shared memory from the system by creating a shared memory */
    /* pool basing it out of the system paging (swapper) file. */

    hFile = CreateFileMapping( (HANDLE) PAGING_FILE,
    NULL,
    PAGE_READWRITE,
    0,
    heap_size + sizeof(Heap_t),
    "MYNAME_SHAREMEM" );
    if (hFile == NULL) {
    return NULL;
    }

    /* Map the file to this process' address space, starting at an address */
    /* that should also be available in child processe(s) */

    hMap = MapViewOfFileEx( hFile, FILE_MAP_WRITE, 0, 0, 0, BASE_MEM );

    info.pBase = hMap;
    if (info.pBase == NULL) {
    return NULL;
    }

    /* Create a fixed sized heap. Put the heap handle as well as the */
    /* base heap address at the beginning of the shared memory. */

    info.pHeap = _ucreate((char *)info.pBase + sizeof(info),
    heap_size - sizeof(info),
    !_BLOCK_CLEAN,
    _HEAP_SHARED | _HEAP_REGULAR,
    NULL, NULL);

    if (info.pBase == NULL) {
    return NULL;
    }

    memcpy(info.pBase, info, sizeof(info));

    if (_uopen(info.pHeap)) { /* Open heap and check result */
    return NULL;
    }

    return info.pHeap;

    }

    /*------------------------------------------------------------------------*/
    /* termhp: */
    /* Function to close and destroy the heap */
    /*------------------------------------------------------------------------*/
    static int termhp(Heap_t uheap)
    {
    if (_uclose(uheap)) /* close heap */
    return 1;
    if (_udestroy(uheap, _FORCE)) /* force destruction of heap */
    return 1;

    UnmapViewOfFile(hMap); /* return memory to system */
    CloseHandle(hFile);

    return 0;
    }

    /*------------------------------------------------------------------------*/
    /* main: */
    /* Main function to test creating, writing to and destroying a shared */
    /* heap. */
    /*------------------------------------------------------------------------*/
    int main(void)
    {
    int i, rc; /* Index and return code */
    Heap_t uheap; /* heap to create */
    void *init_block; /* initial block to use */
    char *p; /* for allocating from heap */

    /* */
    /* call init function to create and open the heap */
    /* */
    uheap = inithp(MEMORY_SIZE);
    if (uheap == NULL) /* check for success */
    return 1; /* if failure, return non zero */

    /* */
    /* perform operations on uheap */
    /* */
    for (i = 1; i <= 5; i++)
    {
    p = _umalloc(uheap, 10); /* allocate from uheap */
    if (p == NULL)
    return 1;
    memset(p, 'M', _msize(p)); /* set all bytes in p to 'M' */
    p = realloc(p,50); /* reallocate from uheap */
    if (p == NULL)
    return 1;
    memset(p, 'R', _msize(p)); /* set all bytes in p to 'R' */
    }

    /* */
    /* Start a second process which accesses the heap */
    /* */
    if (system("memshr2.exe"))
    return 1;

    /* */
    /* Take a look at the memory that we just wrote to. Note that memshr.c */
    /* and memshr2.c should have been compiled specifying the /Tm+ flag. */
    /* */
    #ifdef DEBUG
    _udump_allocated(uheap, -1);
    #endif

    /* */
    /* call term function to close and destroy the heap */
    /* */
    rc = termhp(uheap);

    #ifdef DEBUG
    printf("memshr ending... rc = %d\n", rc);
    #endif

    return rc;
    }

    /* User Heap - Child Process */

    #include <umalloc.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <windows.h>
    #include <winbase.h>

    static HANDLE hFile;       /* Handle to memory file                       */
    static void*  hMap;        /* Handle to allocated memory                  */

    typedef struct mem_info {
      void  * pBase;
      Heap_t  pHeap;

    } MEM_INFO_T;

    /*------------------------------------------------------------------------*/
    /* inithp:  Subprocess Version                                            */
    /* Function to create and open the heap with a named shared memory object */
    /*------------------------------------------------------------------------*/
    static Heap_t inithp(void)
    {

       MEM_INFO_T info;        /* Info structure                              */

       /* Open the shared memory file by name.  The file is based on the      */
       /* system paging (swapper) file.                                       */

       hFile = OpenFileMapping(FILE_MAP_WRITE, FALSE, "MYNAME_SHAREMEM");

       if (hFile == NULL) {
          return NULL;
       }
       /* Figure out where to map this file by looking at the address in the   */
       /* shared memory where the memory was mapped in the parent process.     */

       hMap = MapViewOfFile( hFile, FILE_MAP_WRITE, 0, 0, sizeof(info) );

       if (hMap == NULL) {
          return NULL;
       }

       /* Extract the heap and base memory address from shared memory          */

       memcpy(info, hMap, sizeof(info));
       UnmapViewOfFile(hMap);

       hMap = MapViewOfFileEx( hFile, FILE_MAP_WRITE, 0, 0, 0, info.pBase );

       if (_uopen(info.pHeap)) {          /* Open heap and check result       */
          return NULL;
        }

       return info.pHeap;
    }

    /*------------------------------------------------------------------------*/
    /* termhp:                                                                */
    /* Function to close my view of the heap                                  */
    /*------------------------------------------------------------------------*/
    static int termhp(Heap_t uheap)
    {
       if (_uclose(uheap))                       /* close heap                */
          return 1;

       UnmapViewOfFile(hMap);                    /* return memory to system   */
       CloseHandle(hFile);

       return 0;
    }

    /*------------------------------------------------------------------------*/
    /* main:                                                                  */
    /* Main function to test creating, writing to and destroying a shared     */
    /* heap.                                                                  */
    /*------------------------------------------------------------------------*/
    int main(void)
    {
       int rc, i;                      /* for return code, loop iteration    */
       Heap_t uheap, oldheap;          /* heap to create, old default heap   */
       char *p;                        /* for allocating from the heap       */

       /*                                                                    */
       /* Get the heap storage from the shared memory                        */
       /*                                                                    */
       uheap = inithp();
       if (uheap == NULL)
          return 1;

       /*                                                                    */
       /* Register uheap as default run-time heap, save old default           */
       /*                                                                    */
       oldheap = _udefault(uheap);
       if (oldheap == NULL) {
          return termhp(uheap);
       }

       /*                                                                    */
       /* Perform operations on uheap                                        */
       /*                                                                    */
       for (i = 1; i <= 5; i++)
       {
          p = malloc(10);     /* malloc uses default heap, which is now uheap*/
          memset(p, 'M', _msize(p));
       }

       /*                                                                    */
       /* Replace original default heap and check result                     */
       /*                                                                    */
       if (uheap != _udefault(oldheap)) {
          return termhp(uheap);
       }

       /*                                                                    */
       /* Close my views of the heap                                         */
       /*                                                                    */
       rc = termhp(uheap);

       #ifdef DEBUG
         printf("Returning from memshr2 rc = %d\n", rc);
       #endif
       return rc;

    }

Change the Default Heap

Example of Creating and Using a Heap