COBOL DYNAMIC Operations
Master dynamic memory allocation and variable-length data structures for flexible, efficient memory management in modern COBOL applications.
Overview
Dynamic operations in COBOL provide the ability to allocate and manage memory at runtime, creating flexible data structures that can adapt to changing program requirements. This capability is essential for modern applications that need to handle variable amounts of data efficiently without wasting memory resources.
Dynamic memory management allows programs to request memory as needed, use it for processing, and release it when no longer required. This approach is particularly valuable in applications that process varying amounts of data, implement complex data structures like linked lists or trees, or need to optimize memory usage in resource-constrained environments.
Understanding dynamic operations enables developers to create more efficient and scalable COBOL applications that can handle diverse workloads while maintaining optimal memory utilization and performance characteristics in mainframe and distributed computing environments.
Dynamic Memory Allocation
Basic ALLOCATE Statement
The ALLOCATE statement requests memory at runtime:
123456789101112131415161718192021WORKING-STORAGE SECTION. 01 WS-CUSTOMER-PTR USAGE POINTER. 01 WS-BUFFER-SIZE PIC 9(4) VALUE 1000. 01 WS-ALLOCATION-STATUS PIC 9(2). LINKAGE SECTION. 01 CUSTOMER-BUFFER BASED. 05 CUST-ID PIC X(5). 05 CUST-NAME PIC X(30). 05 CUST-ADDRESS PIC X(50). PROCEDURE DIVISION. ALLOCATE-CUSTOMER-MEMORY. ALLOCATE WS-BUFFER-SIZE CHARACTERS RETURNING WS-CUSTOMER-PTR IF RETURN-CODE = ZERO SET ADDRESS OF CUSTOMER-BUFFER TO WS-CUSTOMER-PTR DISPLAY "Memory allocated successfully" ELSE DISPLAY "Memory allocation failed" END-IF.
This example allocates memory for a customer buffer and sets up pointer-based access to the allocated space.
Structured Data Allocation
Allocating memory for complex data structures:
12345678910111213141516171819202122232425262728WORKING-STORAGE SECTION. 01 WS-POINTERS. 05 WS-HEADER-PTR USAGE POINTER. 05 WS-DATA-PTR USAGE POINTER. 05 WS-INDEX-PTR USAGE POINTER. LINKAGE SECTION. 01 FILE-HEADER BASED. 05 HDR-RECORD-COUNT PIC 9(8). 05 HDR-RECORD-SIZE PIC 9(4). 05 HDR-CREATE-DATE PIC 9(8). 01 DATA-RECORD BASED. 05 REC-KEY PIC X(10). 05 REC-DATA PIC X(100). PROCEDURE DIVISION. ALLOCATE-FILE-STRUCTURES. * Allocate header ALLOCATE LENGTH OF FILE-HEADER CHARACTERS RETURNING WS-HEADER-PTR SET ADDRESS OF FILE-HEADER TO WS-HEADER-PTR * Allocate data area COMPUTE WS-DATA-SIZE = HDR-RECORD-COUNT * HDR-RECORD-SIZE ALLOCATE WS-DATA-SIZE CHARACTERS RETURNING WS-DATA-PTR SET ADDRESS OF DATA-RECORD TO WS-DATA-PTR.
This demonstrates allocating memory for different components of a file structure with calculated sizes.
Dynamic Data Structures
Linked List Implementation
Creating dynamic linked lists using pointers:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950WORKING-STORAGE SECTION. 01 WS-LIST-CONTROL. 05 WS-HEAD-PTR USAGE POINTER VALUE NULL. 05 WS-CURRENT-PTR USAGE POINTER. 05 WS-NEW-NODE-PTR USAGE POINTER. 05 WS-NODE-COUNT PIC 9(5) VALUE ZERO. LINKAGE SECTION. 01 LIST-NODE BASED. 05 NODE-DATA. 10 NODE-ID PIC 9(5). 10 NODE-VALUE PIC X(50). 05 NODE-NEXT-PTR USAGE POINTER VALUE NULL. PROCEDURE DIVISION. ADD-NODE-TO-LIST. * Allocate new node ALLOCATE LENGTH OF LIST-NODE CHARACTERS RETURNING WS-NEW-NODE-PTR IF RETURN-CODE = ZERO SET ADDRESS OF LIST-NODE TO WS-NEW-NODE-PTR * Initialize node data MOVE WS-INPUT-ID TO NODE-ID MOVE WS-INPUT-VALUE TO NODE-VALUE SET NODE-NEXT-PTR TO NULL * Link to list IF WS-HEAD-PTR = NULL SET WS-HEAD-PTR TO WS-NEW-NODE-PTR ELSE PERFORM FIND-LIST-END SET ADDRESS OF LIST-NODE TO WS-CURRENT-PTR SET NODE-NEXT-PTR TO WS-NEW-NODE-PTR END-IF ADD 1 TO WS-NODE-COUNT END-IF. FIND-LIST-END. SET WS-CURRENT-PTR TO WS-HEAD-PTR PERFORM UNTIL WS-CURRENT-PTR = NULL SET ADDRESS OF LIST-NODE TO WS-CURRENT-PTR IF NODE-NEXT-PTR = NULL EXIT PERFORM ELSE SET WS-CURRENT-PTR TO NODE-NEXT-PTR END-IF END-PERFORM.
This creates a dynamic linked list where nodes are allocated as needed and linked together.
Dynamic Array Management
Managing variable-size arrays with dynamic allocation:
123456789101112131415161718192021222324252627282930313233343536373839404142434445WORKING-STORAGE SECTION. 01 WS-ARRAY-CONTROL. 05 WS-ARRAY-PTR USAGE POINTER. 05 WS-ARRAY-SIZE PIC 9(5) VALUE 100. 05 WS-ELEMENT-SIZE PIC 9(3) VALUE 50. 05 WS-CURRENT-ELEMENTS PIC 9(5) VALUE ZERO. 05 WS-MAX-ELEMENTS PIC 9(5). LINKAGE SECTION. 01 DYNAMIC-ARRAY BASED. 05 ARRAY-ELEMENTS OCCURS 1 TO 9999 TIMES DEPENDING ON WS-CURRENT-ELEMENTS. 10 ELEMENT-DATA PIC X(50). PROCEDURE DIVISION. INITIALIZE-DYNAMIC-ARRAY. COMPUTE WS-MAX-ELEMENTS = WS-ARRAY-SIZE / WS-ELEMENT-SIZE COMPUTE WS-ALLOCATION-SIZE = WS-MAX-ELEMENTS * WS-ELEMENT-SIZE ALLOCATE WS-ALLOCATION-SIZE CHARACTERS RETURNING WS-ARRAY-PTR IF RETURN-CODE = ZERO SET ADDRESS OF DYNAMIC-ARRAY TO WS-ARRAY-PTR MOVE ZERO TO WS-CURRENT-ELEMENTS DISPLAY "Dynamic array initialized for " WS-MAX-ELEMENTS " elements" ELSE DISPLAY "Failed to allocate array memory" END-IF. ADD-ELEMENT-TO-ARRAY. IF WS-CURRENT-ELEMENTS < WS-MAX-ELEMENTS ADD 1 TO WS-CURRENT-ELEMENTS MOVE WS-NEW-ELEMENT-DATA TO ELEMENT-DATA(WS-CURRENT-ELEMENTS) DISPLAY "Element added at position " WS-CURRENT-ELEMENTS ELSE PERFORM EXPAND-DYNAMIC-ARRAY IF EXPANSION-SUCCESSFUL PERFORM ADD-ELEMENT-TO-ARRAY END-IF END-IF.
This implements a dynamic array that can grow as needed by reallocating larger memory blocks.
Memory Management Best Practices
Proper Memory Cleanup
Always free allocated memory to prevent memory leaks:
12345678910111213141516171819202122232425262728293031323334353637WORKING-STORAGE SECTION. 01 WS-ALLOCATED-POINTERS. 05 WS-PTR-COUNT PIC 9(3) VALUE ZERO. 05 WS-PTR-TABLE OCCURS 100 TIMES. 10 WS-PTR-ADDRESS USAGE POINTER. 10 WS-PTR-SIZE PIC 9(6). 10 WS-PTR-STATUS PIC X(1) VALUE "F". 88 PTR-ALLOCATED VALUE "A". 88 PTR-FREE VALUE "F". PROCEDURE DIVISION. ALLOCATE-WITH-TRACKING. ADD 1 TO WS-PTR-COUNT ALLOCATE WS-REQUESTED-SIZE CHARACTERS RETURNING WS-PTR-ADDRESS(WS-PTR-COUNT) IF RETURN-CODE = ZERO MOVE WS-REQUESTED-SIZE TO WS-PTR-SIZE(WS-PTR-COUNT) SET PTR-ALLOCATED(WS-PTR-COUNT) TO TRUE DISPLAY "Allocated " WS-REQUESTED-SIZE " bytes at position " WS-PTR-COUNT ELSE SUBTRACT 1 FROM WS-PTR-COUNT DISPLAY "Allocation failed" END-IF. CLEANUP-ALL-MEMORY. PERFORM VARYING WS-INDEX FROM 1 BY 1 UNTIL WS-INDEX > WS-PTR-COUNT IF PTR-ALLOCATED(WS-INDEX) FREE WS-PTR-ADDRESS(WS-INDEX) SET PTR-FREE(WS-INDEX) TO TRUE DISPLAY "Freed memory at position " WS-INDEX END-IF END-PERFORM MOVE ZERO TO WS-PTR-COUNT.
This approach tracks all allocations and ensures proper cleanup to prevent memory leaks.
Error Handling and Validation
Implementing robust error handling for dynamic operations:
123456789101112131415161718192021222324252627282930313233343536373839404142WORKING-STORAGE SECTION. 01 WS-ERROR-HANDLING. 05 WS-LAST-ERROR-CODE PIC 9(2). 05 WS-ERROR-MESSAGE PIC X(80). 05 WS-ALLOCATION-LIMIT PIC 9(8) VALUE 10000000. 05 WS-TOTAL-ALLOCATED PIC 9(8) VALUE ZERO. PROCEDURE DIVISION. SAFE-ALLOCATE. * Validate request size IF WS-REQUESTED-SIZE <= ZERO MOVE 01 TO WS-LAST-ERROR-CODE MOVE "Invalid allocation size" TO WS-ERROR-MESSAGE GO TO SAFE-ALLOCATE-EXIT END-IF * Check allocation limits IF WS-TOTAL-ALLOCATED + WS-REQUESTED-SIZE > WS-ALLOCATION-LIMIT MOVE 02 TO WS-LAST-ERROR-CODE MOVE "Allocation would exceed limit" TO WS-ERROR-MESSAGE GO TO SAFE-ALLOCATE-EXIT END-IF * Attempt allocation ALLOCATE WS-REQUESTED-SIZE CHARACTERS RETURNING WS-NEW-PTR EVALUATE RETURN-CODE WHEN ZERO ADD WS-REQUESTED-SIZE TO WS-TOTAL-ALLOCATED MOVE ZERO TO WS-LAST-ERROR-CODE MOVE "Allocation successful" TO WS-ERROR-MESSAGE WHEN OTHER MOVE RETURN-CODE TO WS-LAST-ERROR-CODE MOVE "System allocation failure" TO WS-ERROR-MESSAGE END-EVALUATE. SAFE-ALLOCATE-EXIT. IF WS-LAST-ERROR-CODE NOT = ZERO DISPLAY "Error " WS-LAST-ERROR-CODE ": " WS-ERROR-MESSAGE END-IF.
This provides comprehensive error checking and resource limit management for safe dynamic allocation.
Advanced Dynamic Techniques
Memory Pool Management
Creating memory pools for efficient allocation:
123456789101112131415161718192021222324252627282930313233343536373839404142434445WORKING-STORAGE SECTION. 01 WS-MEMORY-POOL. 05 WS-POOL-PTR USAGE POINTER. 05 WS-POOL-SIZE PIC 9(8) VALUE 1000000. 05 WS-POOL-USED PIC 9(8) VALUE ZERO. 05 WS-BLOCK-SIZE PIC 9(4) VALUE 1024. 05 WS-FREE-BLOCKS PIC 9(5) VALUE ZERO. 01 WS-FREE-LIST. 05 WS-FREE-HEAD USAGE POINTER VALUE NULL. LINKAGE SECTION. 01 MEMORY-BLOCK BASED. 05 BLOCK-DATA PIC X(1020). 05 BLOCK-NEXT USAGE POINTER. PROCEDURE DIVISION. INITIALIZE-MEMORY-POOL. ALLOCATE WS-POOL-SIZE CHARACTERS RETURNING WS-POOL-PTR IF RETURN-CODE = ZERO PERFORM SETUP-FREE-BLOCKS DISPLAY "Memory pool initialized: " WS-FREE-BLOCKS " blocks available" ELSE DISPLAY "Failed to initialize memory pool" END-IF. ALLOCATE-FROM-POOL. IF WS-FREE-HEAD NOT = NULL SET ADDRESS OF MEMORY-BLOCK TO WS-FREE-HEAD SET WS-FREE-HEAD TO BLOCK-NEXT SUBTRACT 1 FROM WS-FREE-BLOCKS SET WS-ALLOCATED-PTR TO WS-FREE-HEAD ELSE DISPLAY "Memory pool exhausted" SET WS-ALLOCATED-PTR TO NULL END-IF. RETURN-TO-POOL. SET ADDRESS OF MEMORY-BLOCK TO WS-RETURN-PTR SET BLOCK-NEXT TO WS-FREE-HEAD SET WS-FREE-HEAD TO WS-RETURN-PTR ADD 1 TO WS-FREE-BLOCKS.
Memory pools reduce allocation overhead by pre-allocating blocks and managing them efficiently.
Dynamic String Handling
Managing variable-length strings dynamically:
12345678910111213141516171819202122232425262728293031323334353637383940414243WORKING-STORAGE SECTION. 01 WS-STRING-CONTROL. 05 WS-STRING-PTR USAGE POINTER. 05 WS-STRING-LENGTH PIC 9(5). 05 WS-STRING-CAPACITY PIC 9(5). 05 WS-GROWTH-FACTOR PIC 9(1)V9 VALUE 1.5. LINKAGE SECTION. 01 DYNAMIC-STRING BASED. 05 STRING-LENGTH PIC 9(5). 05 STRING-DATA PIC X OCCURS 1 TO 32767 TIMES DEPENDING ON STRING-LENGTH. PROCEDURE DIVISION. CREATE-DYNAMIC-STRING. MOVE WS-INITIAL-LENGTH TO WS-STRING-CAPACITY COMPUTE WS-ALLOCATION-SIZE = WS-STRING-CAPACITY + 5 ALLOCATE WS-ALLOCATION-SIZE CHARACTERS RETURNING WS-STRING-PTR IF RETURN-CODE = ZERO SET ADDRESS OF DYNAMIC-STRING TO WS-STRING-PTR MOVE ZERO TO STRING-LENGTH MOVE ZERO TO WS-STRING-LENGTH END-IF. APPEND-TO-STRING. COMPUTE WS-NEW-LENGTH = WS-STRING-LENGTH + LENGTH OF WS-APPEND-DATA IF WS-NEW-LENGTH > WS-STRING-CAPACITY PERFORM EXPAND-STRING-CAPACITY END-IF IF WS-NEW-LENGTH <= WS-STRING-CAPACITY STRING STRING-DATA(1:WS-STRING-LENGTH) WS-APPEND-DATA INTO WS-TEMP-STRING MOVE WS-TEMP-STRING TO STRING-DATA(1:WS-NEW-LENGTH) MOVE WS-NEW-LENGTH TO STRING-LENGTH MOVE WS-NEW-LENGTH TO WS-STRING-LENGTH END-IF.
This implements dynamic strings that can grow as needed while managing memory efficiently.
Hands-on Exercise
Exercise: Dynamic Customer Database
Create a dynamic customer database that can grow and shrink as needed, with proper memory management.
Requirements:
- Implement dynamic customer record allocation
- Support adding and removing customers
- Include memory tracking and cleanup
- Handle allocation errors gracefully
- Provide memory usage statistics
View Solution
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849WORKING-STORAGE SECTION. 01 WS-DATABASE-CONTROL. 05 WS-CUSTOMER-COUNT PIC 9(5) VALUE ZERO. 05 WS-TOTAL-MEMORY PIC 9(8) VALUE ZERO. 05 WS-CUSTOMER-PTRS OCCURS 1000 TIMES. 10 WS-CUST-PTR USAGE POINTER VALUE NULL. LINKAGE SECTION. 01 CUSTOMER-RECORD BASED. 05 CUST-ID PIC X(5). 05 CUST-NAME PIC X(30). 05 CUST-ADDRESS PIC X(50). 05 CUST-PHONE PIC X(15). PROCEDURE DIVISION. ADD-CUSTOMER. ADD 1 TO WS-CUSTOMER-COUNT ALLOCATE LENGTH OF CUSTOMER-RECORD CHARACTERS RETURNING WS-CUST-PTR(WS-CUSTOMER-COUNT) IF RETURN-CODE = ZERO SET ADDRESS OF CUSTOMER-RECORD TO WS-CUST-PTR(WS-CUSTOMER-COUNT) MOVE WS-INPUT-CUSTOMER TO CUSTOMER-RECORD ADD LENGTH OF CUSTOMER-RECORD TO WS-TOTAL-MEMORY DISPLAY "Customer added successfully" ELSE SUBTRACT 1 FROM WS-CUSTOMER-COUNT DISPLAY "Failed to allocate customer memory" END-IF. REMOVE-CUSTOMER. PERFORM FIND-CUSTOMER-INDEX IF CUSTOMER-FOUND FREE WS-CUST-PTR(WS-FOUND-INDEX) SUBTRACT LENGTH OF CUSTOMER-RECORD FROM WS-TOTAL-MEMORY PERFORM COMPACT-CUSTOMER-ARRAY SUBTRACT 1 FROM WS-CUSTOMER-COUNT END-IF. CLEANUP-DATABASE. PERFORM VARYING WS-INDEX FROM 1 BY 1 UNTIL WS-INDEX > WS-CUSTOMER-COUNT IF WS-CUST-PTR(WS-INDEX) NOT = NULL FREE WS-CUST-PTR(WS-INDEX) END-IF END-PERFORM MOVE ZERO TO WS-CUSTOMER-COUNT MOVE ZERO TO WS-TOTAL-MEMORY.
Quiz
Test Your Knowledge
1. What is the primary advantage of dynamic memory allocation?
2. Which statement is used to release dynamically allocated memory?
3. What is a potential risk of dynamic memory allocation?
View Answers
1. Memory is allocated as needed at runtime - Dynamic allocation provides flexibility to request memory only when needed.
2. FREE - The FREE statement releases dynamically allocated memory back to the system.
3. Memory leaks if not properly freed - Failing to free allocated memory can cause memory leaks and resource exhaustion.