Allocation of Memory in Variable-Length Tables
Say I have the following variable-length table defined in WORKING-STORAGE
...
01 SOAP-RECORD.
05 SOAP-INPUT PIC X(8) VALUE SPACES.
05 SOAP-STATUS PIC 9 VALUE ZERO.
05 SOAP-MESSAGE PIC X(50) VALUE SPACES.
05 SOAP-ITEMS OCCURS 0 TO 500 TIMES
DEPENDING 开发者_运维问答ON ITEM-COUNT
INDEXED BY ITEM-X.
10 SI-SUB-ITEMS OCCURS 0 TO 100 TIMES
DEPENDING ON SUB-COUNT
INDEXED BY SUB-X.
15 SS-KEY PIC X(8) VALUE SPACES.
15 SS-AMOUNT PIC -9(7).99 VALUE ZEROS.
15 SS-DESCR PIC x(100) VALUE SPACES.
When this program runs, will it initially allocate as much space as this table could possibly need, or is it more dynamic about allocating memory? I would guess that the DEPENDING ON
clause would make it more dynamic in the sense that it would allocate more memory as the ITEM-COUNT
variable is incremented. A co-worker tells me otherwise, but he is not 100% sure. So I would really like to know how this works in order to structure my program as efficiently as possible.
PS: Yes, I am writing a new COBOL program! It's actually a CICS web service. I don't think this language will ever die :(
You don't mention which compiler you're using, but, at least up through the current, 2002, COBOL standard, the space allocated for an OCCURS...DEPENDING ON (ODO) data item is not required to be dynamic. (It's really only the number of occurrences, not the length, of the data item that varies.) Although your compiler vendor may've implemented an extension to the standard, I'm not aware of any vendor that has done so in this area.
The next, but not yet approved, revision of the standard includes support for dynamic-capacity tables with a new OCCURS DYNAMIC format.
In the CICS world, OCCURS DEPENDING ON (ODO) can be used to create a
table that is dynamically sized at run time. However, the way you are declaring
SOAP-RECORD
will allocate enough memory to hold a record of maximum size.
Try the following:
First, move the SOAP-RECORD
into LINKAGE SECTION
. Items declared
in the linkage section do not have any memory allocated for them. At this
point you only have a record layout. Leave the declaration of
ITEM-COUNT
and SUB-COUNT
in WORKING-STORAGE
.
Next, declare a pointer and a length in WORKING-STORAGE
something like:
77 SOAP-PTR USAGE POINTER.
77 SOAP-LENGTH PIC S9(8) BINARY.
Finally in the PROCEDURE DIVISION
: Set the size of the array
dimensions to some real values; allocate the
appropriate amount of memory and then connect the two. For example:
MOVE 200 TO ITEM-COUNT
MOVE 15 TO SUB-COUNT
MOVE LENGTH OF SOAP-RECORD TO SOAP-LENGTH
EXEC CICS GETMAIN
BELOW
USERDATAKEY
SET(SOAP-PTR)
FLENGTH(SOAP-LENGTH)
END-EXEC
SET ADDRESS OF SOAP-RECORD TO SOAP-PTR
This will allocate only enough memory to store a SOAP-RECORD with 200 SOAP-ITEMS each of which contain 15 SI-SUB-ITEMS.
Note that the LENGTH OF
register gives you the size of SOAP-RECORD
based on the ODO object values (ITEM-COUNT, SUB-COUNT) as opposed to
the maximum number of OCCURS.
Very important... Don't forget to deallocate the memory when your done!
精彩评论