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 没有问题,因为它引入了语句 ALLOCATE
和 FREE
(注意:这实际上是来自 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.
我有一个通用的 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 没有问题,因为它引入了语句 ALLOCATE
和 FREE
(注意:这实际上是来自 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.