Managing the Default Heap Using RPG Operations

The first request for dynamic storage within an activation group results in the creation of a default heap from which the storage allocation takes place. Additional requests for dynamic storage are met by further allocations from the default heap. If there is insufficient storage in the heap to satisfy the current request for dynamic storage, the heap is extended and the additional storage is allocated.

Allocated dynamic storage remains allocated until it is explicitly freed or until the heap is discarded. The default heap is discarded only when the owning activation group ends.

Programs in the same activation group all use the same default heap. If one program accesses storage beyond what has be allocated, it can cause problems for another program. For example, assume that two programs, PGM A and PGM B are running in the same activation group. 10 bytes are allocated for PGM A, but 11 bytes are changed by PGM A. If the extra byte was in fact allocated for PGM B, problems may arise for PGM B.

You can use the following RPG operations on the default heap:

Note:
Although ALLOC and %ALLOC work only with the default heap, DEALLOC, REALLOC, and %REALLOC work with both the default heap and user-created heaps.

Figure 54 shows an example of how the memory management operation codes can be used to build a linked list of names.

Figure 54. Memory Management - Build a Linked List of Names
      *-----------------------------------------------------------------*
      * Prototypes for subprocedures in this module                     *
      *-----------------------------------------------------------------*
     D AddName         PR
     D   name_parm                   40A
     D Display         PR
     D Free            PR
      *-----------------------------------------------------------------*
      * Each element in the list contains a pointer to the              *
      * name and a pointer to the next element                          *
      *-----------------------------------------------------------------*
     D elem            DS                  BASED(elem@)
     D   name@                         *
     D   next@                         *
     D   name_len                     5U 0
     D nameVal         S             40A    BASED(name@)
     D elemSize        C                   %SIZE(elem)
      *-----------------------------------------------------------------*
      * The first element in the list is in static storage.             *
      * The name field of this element is not set to a value.           *
      *-----------------------------------------------------------------*
     D first           DS
     D                                 *   INZ(*NULL)
     D                                 *   INZ(*NULL)
     D                                5U 0 INZ(0)
      *-----------------------------------------------------------------*
      * This is the pointer to the current element.                     *
      * When elem@ is set to the address of <first>, the list is        *
      * empty.                                                          *
      *-----------------------------------------------------------------*
     D elem@           S               *   INZ(%ADDR(first))
      *-----------------------------------------------------------------*
      * Put 5 elements in the list                                      *
      *-----------------------------------------------------------------*
     C                   DO        5
     C     'Name?'       DSPLY                   name             40
     C                   CALLP     AddName(name)
     C                   ENDDO

      *-----------------------------------------------------------------*
      * Display the list and then free it.                              *
      *-----------------------------------------------------------------*
     C                   CALLP     Display
     C                   CALLP     Free
     C                   EVAL      *INLR = '1'

      *-----------------------------------------------------------------*
      * S U B P R O C E D U R E S                                       *
      *-----------------------------------------------------------------*
      *-----------------------------------------------------------------*
      * AddName - add a name to the end of the list                     *
      *-----------------------------------------------------------------*
     P AddName         B
     D AddName         pi
     D   name                        40A
      *-----------------------------------------------------------------*
      * Allocate a new element for the array, pointed at by the         *
      * 'next' pointer of the current end of the list.                  *
      *                                                                 *
      * Before:                                                         *
      *                                                                 *
      *  .-------------.                                                *
      *  |             |                                                *
      *  | name     *--->abc                                            *
      *  | name_len 3  |                                                *
      *  | next     *-------|||                                         *
      *  |             |                                                *
      *  '-------------'                                                *
      *                                                                 *
      *-----------------------------------------------------------------*
     C                   ALLOC     elemSize      next@
      *-----------------------------------------------------------------*
      *                                                                 *
      * After: Note that the old element is still the current one       *
      *        because elem@ is still pointing to the old element       *
      *                                                                 *
      *  .-------------.               .--------------.                 *
      *  |             |       .------>|              |                 *
      *  | name     *--->abc   |       |              |                 *
      *  | name_len 3  |       |       |              |                 *
      *  | next     *----------'       |              |                 *
      *  |             |               |              |                 *
      *  '-------------'               '--------------'                 *
      *                                                                 *
      * Now set elem@ to point to the new element                       *
      *-----------------------------------------------------------------*
     C                   EVAL      elem@ = next@
      *-----------------------------------------------------------------*
      *                                                                 *
      * After: Now the names name@, name_len and next@ refer            *
      *        to storage in the new element                            *
      *                                                                 *
      *  .-------------.               .--------------.                 *
      *  |             |       .------>|              |                 *
      *  |          *--->abc   |       | name      *  |                 *
      *  |          3  |       |       | name_len     |                 *
      *  |          *----------'       | next      *  |                 *
      *  |             |               |              |                 *
      *  '-------------'               '--------------'                 *
      *                                                                 *
      * Now set the values of the new element.                          *
      * The next pointer is set to *NULL to indicate that it is the     *
      * end of the list.                                                *
      *-----------------------------------------------------------------*
     C                   EVAL      next@ = *NULL
      *-----------------------------------------------------------------*
      * Save the length of the name (not counting trailing blanks)
      *-----------------------------------------------------------------*
     C                   EVAL      name_len = %len(%trimr(name))
      *-----------------------------------------------------------------*
      * Storage is allocated for the name and then set to the value of
      * the name.
      *-----------------------------------------------------------------*
     C                   ALLOC     name_len      name@
     C                   EVAL      %SUBST(nameVal:1:name_len) = name
      *-----------------------------------------------------------------*
      *                                                                 *
      * After:                                                          *
      *                                                                 *
      *  .-------------.               .--------------.                 *
      *  |             |       .------>|              |                 *
      *  |          *--->abc   |       | name      *--->newname         *
      *  |          3  |       |       | name_len  nn |                 *
      *  |          *----------'       | next      *--->|||             *
      *  |             |               |              |                 *
      *  '-------------'               '--------------'                 *
      *-----------------------------------------------------------------*
     P AddName         E
      *-----------------------------------------------------------------*
      * Display - display the list                                      *
      *-----------------------------------------------------------------*
     P Display         B
     D saveElem@       S               *
     D dspName         S             40A
      *-----------------------------------------------------------------*
      * Save the current elem pointer so the list can be restored after *
      * being displayed and set the list pointer to the beginning of    *
      * the list.                                                       *
      *-----------------------------------------------------------------*
     C                   EVAL      saveElem@ = elem@
     C                   EVAL      elem@ = %ADDR(first)
      *-----------------------------------------------------------------*
      * Loop through the elements of the list until the next pointer is *
      * *NULL                                                           *
      *-----------------------------------------------------------------*
     C                   DOW       next@ <> *NULL
     C                   EVAL      elem@ = next@
     C                   EVAL      dspName = %SUBST(nameVal:1:name_len)
     C     'Name: '      dsply                   dspName
     C                   ENDDO
      *-----------------------------------------------------------------*
      * Restore the list pointer to its former place
      *-----------------------------------------------------------------*
     C                   EVAL      elem@ = saveElem@
     P Display         E
      *-----------------------------------------------------------------*
      * Free - release the storage used by the list                     *
      *-----------------------------------------------------------------*
     P Free            B
     D prv@            S               *
      *-----------------------------------------------------------------*
      * Loop through the elements of the list until the next pointer is *
      * *NULL, starting from the first real element in the list         *
      *-----------------------------------------------------------------*
     C                   EVAL      elem@ = %ADDR(first)
     C                   EVAL      elem@ = next@
     C                   DOW       elem@ <> *NULL
      *-----------------------------------------------------------------*
      * Free the storage for name                                       *
      *-----------------------------------------------------------------*
     C                   DEALLOC                 name@
      *-----------------------------------------------------------------*
      * Save the pointer to current elem@
      *-----------------------------------------------------------------*
     C                   EVAL      prv@ = elem@
      *-----------------------------------------------------------------*
      * Advance elem@ to the next element
      *-----------------------------------------------------------------*
     C                   EVAL      elem@ = next@

      *-----------------------------------------------------------------*
      * Free the storage for the current element
      *-----------------------------------------------------------------*
     C                   DEALLOC                 prv@
     C                   ENDDO

      *-----------------------------------------------------------------*
      * Ready for a new list:
      *-----------------------------------------------------------------*
     C                   EVAL      elem@ = %ADDR(first)
     P Free            E


[ Top of Page | Previous Page | Next Page | Contents | Index ]