COBOL 中的动态内存分配

Dynamic memory allocation in COBOL

我有一个通用的 C 函数,我想从 C、Fortran 和 COBOL 中调用它。它从数据库中获取 x 字节的数据并将其放置在提供给它的 char 指针中。我下面的示例获取 1024 字节,但在实际情况下,我希望能够获取比 1024 字节大得多的数据块,因此需要动态内存分配。

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);
}

我能够从 C 中成功调用此函数。

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

我也能够从 Fortran 中成功调用此函数。

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

但是如何在 COBOL 中分配和解除分配动态内存?为此,我一直无法找到内置 functions/procedures。

我也没有看到 C 可以处理 Fortran 和 COBOL 的分配和释放的替代方案,因为它们需要访问 C 之外的数据。

如果不需要内存中的全部数据,则考虑使用 chunk-by-chunk:在 COBOL 中分配 fixed-size 存储空间,使用 C 函数将块取入其中,使用它并循环继续下一个块。这样你就可以完全避免分配动态内存。

一个非常古老的编译器示例 (Micro Focus COBOL v3.2.50)。其中大部分内容直接取自补充材料。由于我没有可用的同样旧的 C 编译器,因此我包含了一个 COBOL 程序作为副标题。

   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".

显示(修剪)为:

 abcdabcdabcdabcd...(for 1024 characters total)

也许这会有所帮助。

由于您只谈到了 "COBOL" 而没有指定任何实际实现,我假设您的意思是 "standard COBOL"。

这可能意味着 COBOL85 - 它没有此功能但允许您只定义 DATA-FOR-C PIC X(1024) 并将其作为参考传递(COBOL85 实际上没有指定任何关于调用 C space但这应该适用于大多数(如果不是全部)COBOL 实现)。注意:这实际上是Acorns回答的更多细节。

如果您想使用真正的动态内存分配并且您的意思是标准 COBOL - COBOL 2002 没有问题,因为它引入了语句 ALLOCATEFREE(注意:这实际上是来自 roygvib 和 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

如果您不使用支持这些语句的 COBOL 实现,则必须使用实现者特定的例程(通常通过 CALL)来 get/release 内存。

  • MicroFocus/NetCOBOL(参见 Rick 的回答):CBL_ALLOC_MEM/CBL_FREE_MEM[2]
  • ACUCOBOL:M$ALLOC/M$FREE
  • IBM:CEEGTST
  • 允许直接调用 C 函数的任何 COBOL 编译器和运行时(可能 添加额外的需求,为那些指定适当的 CALL-CONVENTION):malloc/free
  • ...请参阅您的实施手册...

如果您使用的是 Z 或使用 Gnu Cobol,您只需调用 malloc():

        CALL "malloc" USING BY VALUE MEM-SIZE
             RETURNING MEM-PTR.

        CALL "free" USING BY VALUE MEM-PTR.