Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic memory allocation in COBOL

I have a common C function that I want to call from C, Fortran and COBOL. It fetches x bytes of data from a database and places it in a char pointer supplied to it. My example below fetches 1024 bytes, but in the real situation I want to be able to fetch much larger chunks of data than 1024 bytes as well, hence the dynamic memory allocation.

void fetch_data(char *fetched)
{
    static struct {unsigned long data_length; char some_data[1024];} a_struct;
    // Fetch data into a_struct.
    memcpy(fetched, &(a_struct.some_data), 1024);
}

I was able to call this function successfully from C.

char *mydata;
mydata = malloc(1024);
fetch_data(mydata);
// Do something with the data.
free(mydata);

I was also able to call this function successfully from Fortran.

INTEGER*4, ALLOCATABLE :: MYDATA(:)
ALLOCATE(MYDATA(1024))
CALL FETCH_DATA(MYDATA)    
// Do something with the data.
DEALLOCATE(MYDATA)

But how do I allocate and deallocate dynamic memory in COBOL? I have been unable to find built-in functions/procedures for this purpose.

I also don't see an alternative where C could handle the allocation and deallocation for Fortran and COBOL, as they need to access the data outside C.

like image 426
Helena Avatar asked Dec 05 '22 12:12

Helena


2 Answers

As you've only talked about "COBOL" without specifying any actual implementation I assume you mean "standard COBOL".

This could mean COBOL85 - which doesn't have this feature but allows you to just define DATA-FOR-C PIC X(1024) and pass this as reference (COBOL85 actually doesn't specify anything about calling into C space but this should work with most if not all COBOL implementations). Note: This is actually more a detail of Acorns answer.

If you want to use real dynamic memory allocation and you mean standard COBOL - no problem with COBOL 2002 as it introduced the statements ALLOCATE and FREE (Note: this is actually the detail of the comments from roygvib and Rick):

77 pointer-variable  USAGE POINTER.
77 address-holder    PIC X BASED.

ALLOCATE variable-number CHARACTERS RETURNING pointer-variable
SET ADDRESS OF address-holder TO pointer-variable
CALL "fetch_data" USING address-holder
PERFORM stuff
FREE pointer-variable

If you don't use a COBOL implementation that support these statements you'd have to use the implementor specific routines (normally via CALL) to get/release the memory.

  • MicroFocus/NetCOBOL (see answer of Rick): CBL_ALLOC_MEM/CBL_FREE_MEM[2]
  • ACUCOBOL: M$ALLOC/M$FREE
  • IBM: CEEGTST
  • any COBOL compiler and runtime that allows to directly call C functions (which may adds additional needs as specifying the appropriate CALL-CONVENTION for those): malloc/free
  • ... see your implementor's manual ...
like image 112
Simon Sobisch Avatar answered Jan 21 '23 19:01

Simon Sobisch


One example with a very old compiler (Micro Focus COBOL v3.2.50). Much of this is taken directly from the supplemental materials. And since I didn't have an equally old C compiler available, I included a COBOL program as a subtitute.

   program-id. dynam.
   data division.
   working-storage section.
   1 ptr pointer.
   1 mem-size pic x(4) comp-5 value 1024.
   1 flags pic x(4) comp-5 value 1.
   1 status-code pic x(2) comp-5.
   linkage section.
   1 mem pic x(1024).
   procedure division.
       call "CBL_ALLOC_MEM" using ptr
           by value mem-size flags
         returning status-code
       if status-code not = 0
           display "memory allocation failed"
           stop run
       else
           set address of mem to ptr
       end-if

       call "fetch_data" using mem
       display mem

       call "CBL_FREE_MEM" using mem
         returning status-code
       if status-code not = 0
           display "memory deallocation failed"
           stop run
       else
           set address of mem to null
       end-if
       stop run
       .
   end program dynam.

   program-id. "fetch_data".
   data division.
   working-storage section.
   1 some-struct pic x(1024) value all "abcd".
   linkage section.
   1 mem pic x(1024).
   procedure division using mem.
       move some-struct to mem
       exit program
       .
   end program "fetch_data".

The display (trimmed) is:

 abcdabcdabcdabcd...(for 1024 characters total)

Maybe that will be of some help.

like image 34
Rick Smith Avatar answered Jan 21 '23 17:01

Rick Smith