Dynamic Memory Allocation
March 28, 1996by Bob Cavanagh
This article demonstrates some useful techniques for dynamic memory allocation. Many software applications, including the Acucobol runtime system, must have a mechanism for allocating memory dynamically. This is because they have no way of knowing how much memory they will need when they are first launched.
Developers who don't have this capability often struggle with design issues and must often include large tables in the data division to compensate for "worst-case" scenarios. Typically, this presents a double disadvantage: lack of flexibility and wasted memory. Because situations can change rapidly, the "worst case" of today may be the "best case" of tomorrow. Without built-in flexibility, the developer who needs more memory has no recourse other than to rewrite portions of the application.
Acucobol gives the application developer the ability to allocate memory dynamically and manipulate data within that allocated memory via a number of library routines. These routines are:
- M$ALLOC Dynamically allocates the amount of memory specified by the application developer
- M$PUT Populates the dynamically allocated memory area with data
- M$GET Retrieves data from the dynamically allocated memory area
- M$FREE Frees the dynamically allocated memory
- C$MEMCPY Copies a number
of bytes specified by the application developer from a memory area (indicated
by a pointer) supplied by the application developer to another memory area
(indicated by a pointer) supplied by the application developer.
- SET ADDRESS OF [linkage-item] TO {pointer}
- {ADDRESS OF [data-item]}
- {NULL}
The best way to understand these routines is to use them. The following program is designed to clarify how to use each feature.
identification division.
program-id. dynamic-m.
environment division.
data division.
working-storage section.
* Data items for M$ALLOC library routine.
01 item-size pic 9(5) value 0.
01 mem-address usage pointer.
*
01 data-item pic x(4).
01 dest-item pic x(60).
01 data-offset pic 9(5) value 1.
*
01 ctr pic 9(4) value 0.
linkage section.
01 dynamic-area pic x(60).
procedure division using dynamic-area.
main.
display window erase.
display "Dynamic Memory Allocation Examples"
line 5 col 1 reverse.
* M$ALLOC is passed item-size, and it returns a pointer
* to mem-address. In the example below, we want to
* allocate 32K of new memory. If the allocation were to
* fail, a NULL value would be returned to mem-address.
* Note that in the Acucobol Debugger, after this
* operation succeeds, you can type "U" at the debugger
* prompt, and you will see the new memory listed under
* the DYNAMIC: amount.
move 60 to item-size.
call "M$ALLOC" using item-size, mem-address.
* Typically, you would not be dynamically allocating
* memory unless you needed to use it. M$PUT is designed
* to put data into the dynamically allocated memory block.
* In the call to M$PUT, your instructions are to place
* data-item into the memory area indicated by mem-address.
* You have the ability to put the data to an offset in
* the memory area, and you have the ability to put only
* data-size bytes of data-item into the memory area, or
* to an offset therein, but both of these parameters are
* optional.
* In the following loop, the numbers from 1 to 1000 are
* stored in a dynamically created memory area:
if mem-address = NULL
display "Memory Allocation Failed" line 10 col 10
display "Press any Key..." line 22 col 50
accept omitted
stop run
else
move 1 to data-offset
perform varying ctr from 1 by 1 until ctr > 15
call "M$PUT" using mem-address, ctr,
4, data-offset
add 4 to data-offset
end-perform
end-if.
* At some point in time, you will want to retrieve this
* data from the dynamically allocated memory area. M$GET
* is similar to M$PUT, but is designed to retrieve,
* rather than to store the data:
* The following loop retrieves the first 20 numbers, and
* displays them, one per line.
move 1 to data-offset.
display "M$GET: " line 12, col 1.
perform varying ctr from 1 by 1 until ctr > 15
call "M$GET" using mem-address, data-item,
4, data-offset
add 4 to data-offset
display data-item, col + 1
end-perform.
accept omitted.
* The last of the dynamic memory library routines is
* C$MEMCPY. C$MEMCPY can be used to transfer a designated
* number of bytes from within one dynamically allocated
* memory area to another one, or to a data-item in
* working-storage, which is identified by a pointer, or
* given a BY-REFERENCE designation. Of all the dynamic
* memory library routines, this is the one that contains
* the least error checking, and therefore offers the
* greatest potential for generating memory access
* violations when passed incorrect data.
call "C$MEMCPY" using by reference dest-item,
by value mem-address, 60.
display "MemCpy: " line 13 col 1, dest-item.
accept omitted.
* You can use the linkage section to create a definition
* template for dynamically allocated memory. This can
* also be useful, in that it gives you an opportunity to
* introduce the Acucobol Debugger to view contents of
* memory, even when you have not compiled with -Zs or -Zd.
* At the debugger prompt, type:
* "D 0,60,p0" to display the first 60 bytes, starting at
* offset 0, of the first parameter; in this case,
* dynamic-area.
set address of dynamic-area to mem-address.
display "Linkage: " line 14 col 1, dynamic-area.
accept omitted.
* Cleanup is important. We will call M$FREE to free up
* dynamically allocated memory before leaving this
* application. After executing this command, you will
* notice in the Debugger that the "U" command no longer
* lists the dynamically allocated memory.
call "M$FREE" using mem-address.
display window erase.
stop run.
Frequently Asked Questions
Q. Is it possible to view the contents of dynamically allocated memory in the debugger?
A. If you use the SET ADDRESS
OF [LINKAGE-ITEM] to {POINTER} formula, you can view the contents of dynamically
allocated memory. (This is true of any linkage parameter.)
When referring to linkage
parameters, append "p[#]" to the address, where [#] represents the item's
position in the USING phrase of the procedure division header. The command
"D 0,10,p0" will display the first 10 bytes, starting at offset 0, of the
first parameter.
Q. Should I be concerned about Memory Access Violations when dynamically allocating memory?
A. Yes, you should, although
the library routines do provide some protection against memory access violations.
The following are common
causes of memory access violations:
- M$ALLOC: Attempting to allocate memory should not cause a memory access violation. The function will either succeed, or fail, and the latter case will return NULL to the pointer, and will not abort your program.
- M$PUT: Attempting to put data in an invalid memory area will have unpredictable consequences. Among the possibilities are memory access violations. However, the routine does protect the programmer somewhat, in that it will not attempt to copy bytes that exceed the size of the memory block you have allocated.
- M$GET: Attempting to retrieve data from an invalid memory area can cause a memory access violation. In Unix systems, this would likely show up as a Segmentation Fault. Like M$PUT, M$GET recognizes the size of the allocated memory block, and will not attempt to retrieve data outside of those bounds, though.
- C$MEMCPY: This is the most dangerous of the routines, because it does no error checking. It will cause memory access violations if you pass it incorrect data.
Q. What is the smallest amount of memory that can be dynamically allocated?
A. You can allocate as little as 1 byte of memory, or as much as your system will allow. There will be between 4 and 16 bytes of overhead for a dynamic memory allocation, depending on the system.
We hope this example demonstrates how these convenient Acucobol routines give the developer significant flexibility for allocating memory dynamically and for manipulating the data within the allocated memory.
####
Acucorp, extend and ACUCOBOL are trademarks or registered trademarks of Acucorp, Inc. All rights reserved. All other trademarks are the property of their respective owners.

























