MVSFORUMS.com Forum Index MVSFORUMS.com
A Community of and for MVS Professionals
 
 FAQFAQ   SearchSearch   Quick Manuals   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Dynamic define of size of array in COBOL batch program

 
Post new topic   Reply to topic   printer-friendly view    MVSFORUMS.com Forum Index -> Application Programming
View previous topic :: View next topic  
Author Message
SHANKS
Beginner


Joined: 04 Jul 2007
Posts: 2
Topics: 2

PostPosted: Sat Jul 07, 2007 10:41 am    Post subject: Dynamic define of size of array in COBOL batch program Reply with quote

How do you dynamically define the size of array("occurs ") during runtime in COBOL programs ?
Back to top
View user's profile Send private message
dbzTHEdinosauer
Supermod


Joined: 20 Oct 2006
Posts: 1411
Topics: 26
Location: germany

PostPosted: Sat Jul 07, 2007 11:43 am    Post subject: Reply with quote

you can't.

What you can do, is GETMAIN (or use whatever LE -Language Environment service is available on your OPSYS and acquire additional runtime memory) and assign a table definition to the new area, but a COBOL Table defined in working storage has only one size, the max occurs.

A COBOL Table defined with ODO (occurs depending on) will be assigned the size of the max occurs; though for purposes of Statements such a SEARCH, using the ODO will cause the Search to only look at the number of items declared by the value contained in the ODO object - the counter.
_________________
Dick Brenholtz
American living in Varel, Germany
Back to top
View user's profile Send private message
blitz2
Beginner


Joined: 23 Jan 2007
Posts: 84
Topics: 14

PostPosted: Mon Jul 09, 2007 12:44 am    Post subject: Reply with quote

Code:

01 WS-TABLE-EG.
   10 WS-TABLE-COUNT PIC S9(4) BINARY.
   10 WS-TABLE-DATA-ALL.
       20 WS-TABLE-DATA OCCURS 10 TIMES
                                     DEPENDING ON WS-TABLE-COUNT
                                     INDEXED BY WS-TABLE-IDX.
            25 WS-TABLE-MESSAGE PIX X(20).


If it is included in WORKING-STORAGE, as Dbz said, it is going to get storage equal to max times (10, in this case)

If you put it in LINKAGE SECTION, and no memory is assigned at the entry point, then you need to do a GETMAIN like,

Code:

EXEC CICS
   GETMAIN
   SET (ADDRESS OF WS-TABLE-EG)
   FLENGTH(3000)
   INITMG (X'40')
END-EXEC


you can control table 'occurs' through WS-TABLE-COUNT.

I would recommend you try a small program for better understanding.
________
Kissing Advice Advice


Last edited by blitz2 on Thu Mar 10, 2011 5:31 pm; edited 1 time in total
Back to top
View user's profile Send private message
dbzTHEdinosauer
Supermod


Joined: 20 Oct 2006
Posts: 1411
Topics: 26
Location: germany

PostPosted: Mon Jul 09, 2007 2:17 am    Post subject: Reply with quote

As a follow-up to Blitz's excellent post:

Unlike C, VB, JAVA & REXX, where you can just keep on dynamically adding 'occurs', COBOL Tables are based on contiguous memory - it is required by the code to address each item.

In the C, VB & JAVA languages and REXX Scripts, the table items are not required to be in contiguous memory - the concept of contiguous memory does not belong to those languages - which is why you can, continuously, dynamically allocate 'occurs' during runtime.

In COBOL, once you have dynamically allocated additional memory (GETMAIN in CICS, LE memory acquisition in Batch), that memory is one (1) table definition. If you then acquire more memory, the second and subsequent memory allocations have to be addressed as separate tables. i.e. you can not 'extend' a COBOL Table with a second dynamic memory allocation.
_________________
Dick Brenholtz
American living in Varel, Germany
Back to top
View user's profile Send private message
dz
Beginner


Joined: 02 Apr 2006
Posts: 26
Topics: 0

PostPosted: Mon Jul 09, 2007 12:43 pm    Post subject: Reply with quote

Actually, this is possible to do, with caveats. I did something similar in CICS program via GETMAIN, and I'm sure could be done in batch using CEEGTST.
Here is what I did:
1) COBOL OCCURS has to be 1 and counld reside in the LINKAGE or WS
2) Compile ALWAYS with NOSSRANGE
3) Allocate Max memory by calculating number of bytes = <occurs element length> * <Max number of elements>
4) Assign address of newly allocated memory to array in linkage
5) Redefine the Pointer as follows:
05 LINK-ADDRSS USAGE IS POINTER.
05 LINK-ADDRSS-RE REDEFINES LINK-ADDRSS PIC S9(08) COMP.
5) Walk the array (up to <Max number of elements>) by increasing the address in LINK-ADDRSS-RE by simple addition of the <occurs element length>. Reset the address of COBOL array to point to LINK-ADDRSS
6) ALWAYS use index of 1 when referencing array element
7) Good idea to save your original address, for FREEMAIN (or CEEFRST) purposes
Back to top
View user's profile Send private message
DaveyC
Moderator


Joined: 02 Dec 2002
Posts: 151
Topics: 3
Location: Perth, Western Australia

PostPosted: Thu Jul 12, 2007 2:16 am    Post subject: Reply with quote

dbzTHEdinosauer wrote:

In the C, VB & JAVA languages and REXX Scripts, the table items are not required to be in contiguous memory - the concept of contiguous memory does not belong to those languages - which is why you can, continuously, dynamically allocate 'occurs' during runtime.
.


In C an array is contiguous, same for Java. C++ and Java have vector containers, which are also contiguous. Almost all random access containers are contiguous, otherwise they cannot guarantee a constant time complexity, O(1). Of course, REXX compound variables are hash tables, so you're right there...
_________________
Dave Crayford
Back to top
View user's profile Send private message Send e-mail
dbzTHEdinosauer
Supermod


Joined: 20 Oct 2006
Posts: 1411
Topics: 26
Location: germany

PostPosted: Thu Jul 12, 2007 4:48 am    Post subject: Reply with quote

DaveyC,

thanks for the correction, and education.
dick
_________________
Dick Brenholtz
American living in Varel, Germany
Back to top
View user's profile Send private message
jsharon1248
Intermediate


Joined: 08 Aug 2007
Posts: 291
Topics: 2
Location: Chicago

PostPosted: Wed Aug 08, 2007 2:21 pm    Post subject: Reply with quote

I'll go one step further on dz's excellent recommendation to aquire storage using LE service CEEGTST. I use CEEGTST in COBOL to create linked lists. I'd recommend using the linked list rather than bothering with tables and increasing displacements. It's fairly straightforward.
Code:

WORKING STORAGE SECTION.

01  IN-REC.
   03  FLD1  PIC X(10).
   03  FLD2  PIC X(02).

01  CEEGTST-PARM-AREA.                                         
    05  CEEGTST-HEAP-ID             PIC S9(09) COMP VALUE +0. 
    05  CEEGTST-BYTES-QTY           PIC S9(09) COMP.           
    05  CEEGTST-STORAGE-ADDR            USAGE IS POINTER.     

01  LINKED-LIST-ANCHOR  POINTER.

LINKAGE SECTION.
01  LS-ELEMENT.
   03  LS-NEXT-ITEM  POINTER.
   03  LS-VAL1   PIC X(10).
   03  LS-VAL2   PIC X(02).

PROCEDURE DIVISION USING LS-ELEMENT.
.
.
.
*** CREATE LINKED LIST
READ IN-FLE INTO IN-REC
PERFORM GET-STORAGE
SET LINKED-LIST-ANCHOR TO CEEGTST-STORAGE-ADDR
PERFORM UNTIL <IN-FLE end of file>
  SET ADDRESS OF LS-ELEMENT TO CEEGTST-STORAGE-ADDR
  MOVE FLD1 TO LS-VAL1
  MOVE FLD2 TO LS-VAL2
  PERFORM GET-STORAGE
  SET LS-NEXT-ITEM TO CEEGTST-STORAGE-ADDR
  READ IN-FLE INTO IN-REC
END-PERFORM
SET LS-NEXT-ITEM TO NULL

*** RETRIEVE ELEMENTS FROM LINKED LIST
SET ADDRESS OF LS-ELEMENT TO LINKED-LIST-ANCHOR
PERFORM UNTIL LS-NEXT-ITEM = NULL
  DISPLAY 'LS-VAL1: ' LS-VAL1
  DISPLAY 'LS-VAL2: ' LS-VAL2
  SET ADDRESS OF LS-ELEMENT TO LS-NEXT-ITEM
END-PERFORM

GET-STORAGE.
  MOVE LENGTH OF LS-ELEMENT TO CEEGTST-BYTES-QTY 
  SET CEEGTST-STORAGE-ADDR TO NULL         
  CALL 'CEEGTST' USING CEEGTST-HEAP-ID     
                     CEEGTST-BYTES-QTY   
                     CEEGTST-STORAGE-ADDR
                     OMITTED
  .
GET-STORAGE-EXIT. EXIT.


This is obviously a contrived example and the syntax is most likely flawed, but the overall idea is accurate. I used this on multiple occasions when the occurences varies widely from one run to the next. It can also be used when the size of the individual elements varies. To vary the length of the individual elements, just define a very large area in the linkage section, LS-VAL PIC X(2000), but only request the amount you need from CEEGTST. You'd need to store the length of each element too and only reference data within that length. COBOL will allow you to access the full length defined and as IBM likes to say, the results are unpredictable.

Here's a link for the LE services:
http://publibz.boulder.ibm.com/epubs/pdf/ceea3031.pdf
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic   printer-friendly view    MVSFORUMS.com Forum Index -> Application Programming All times are GMT - 5 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


MVSFORUMS
Powered by phpBB © 2001, 2005 phpBB Group