Allocating and Deallocating Memory

Allocating memory in other languages

The C language provides a built-in mechanism for allocating memory at run time. You call the malloc() function, telling it how many bytes you want. It allocates the memory and returns a pointer to it, which is NULL if the requested memory is not available.

When you no longer need that chunk of memory, you deallocate it by passing the pointer to the free() function. The memory management system magically remembers how big that chunk is, and reclaims the memory (potentially for further allocations later).

Similar facilities are available in other languages such as C++ and Pascal. This scheme is so convenient that it is commonplace to allocate memory dynamically whenever you need to store a character string, instead of using an array with a hard-coded size.

Allocating memory in COBOL

Traditional COBOL does not allocate memory dynamically. Character strings and other objects generally have fixed lengths, hard-coded in WORKING-STORAGE.

Some dialects of COBOL, including COBOL 370, provide special facilities for allocating and deallocating memory. CICS has special commands for this purpose as well.

Most of JOCKEY was written in COBOL II, where no such facility is available. Instead, JOCKEY uses some Assembler routines, which are wrappers for GETMAIN and FREEMAIN macros. However, these routines incur a fair amount of overhead. They are also cumbersome to use because you must tell the FREEMAIN wrapper how many bytes to free.

In part for these reasons, JOCKEY encapsulates these routines in the JK011 module, which manages pools of variously-sized pieces of memory.

Allocating multiple pieces at a time

When maintaining data structures, you generally juggle multiple instances of the same kind of object. One way to allocate them is to declare an array of those objects in WORKING-STORAGE. Whenever you need another instance, increment a subscript that keeps track of the number allocated. Naturally you must make sure you don't exceed the array size.

The JK011 routines extend this approach by allocating arrays dynamically as needed. For each memory pool opened by a call to MCBOPEN, JK011 maintains a linked list of arrays. When you call MCBITEM to allocate an individual item, MCBITEM allocates it from the current array. If the current array is already exhausted, MCBITEM allocates another array and adds it to the list.

This approach is a compromise between efficiency and flexibility. With only a few expensive calls to GETMAIN and FREEMAIN, the application can get as much memory as it needs, without declaring a single huge array in WORKING-STORAGE that will be mostly unused.

Deallocation

How you deallocate something depends on how you allocate it. If you allocate objects one at a time through a facility such as malloc() or GETMAIN, you can probably deallocate it through a matching facility such as free() or FREEMAIN.

Likewise if you allocate multiple objects at a time, you can deallocate multiple objects at a time. If you allocate from a WORKING-STORAGE table, you can reset your subscript. If you allocate from a memory pool created by MCBOPEN, you can call MCBCLEAR or MCBFREE.

Usually, though, you want to be able to deallocate one object at a time. Otherwise you can't remove nodes from your data structures without incurring a memory leak. The solution is to maintain a free list.


[home]COBOL Home [pointer]Pointer Variables [structure]Data Structures