Ada 大型阵列引发错误的内存访问
有没有办法让代码正常工作?我想创建一个大小为10mio的数组。地址。但是运行这段代码会引发一个*约束\错误:错误的内存访问*Ada 大型阵列引发错误的内存访问,ada,Ada,有没有办法让代码正常工作?我想创建一个大小为10mio的数组。地址。但是运行这段代码会引发一个*约束\错误:错误的内存访问* procedure Main is type A_Type is abstract tagged null record; type B_Type is new A_Type with null record; type B_Type_Access is access all B_Type; type C is array (1 .. 10_0
procedure Main is
type A_Type is abstract tagged null record;
type B_Type is new A_Type with null record;
type B_Type_Access is access all B_Type;
type C is array (1 .. 10_000_000) of B_Type_Access;
D : C;
begin
null;
end Main;
我猜在堆栈中创建变量D太多了。尝试在池中创建访问变量数组,如下所示:
PROCEDURE Main IS
TYPE A_Type IS ABSTRACT TAGGED NULL RECORD;
TYPE B_Type IS NEW A_Type WITH NULL RECORD;
TYPE B_Type_Access IS ACCESS ALL B_Type;
TYPE C IS ARRAY (1 .. 10_000_000) OF B_Type_Access;
TYPE E IS ACCESS C;
D : E;
BEGIN
D := NEW C;
END Main;
多克托先生有一个很好的解决办法。另一种方法是将数组(以及所有类型)放入一个包中(我假设
Main
不会递归地调用自身):
现在,由于数组
C
不再位于过程中,它将被分配到常规数据内存中,而不是堆栈中。Ada中的变量通常被分配到堆栈中。这意味着您必须确保允许您的进程为您声明的变量拥有足够大的堆栈
在Linux系统上,可以使用ulimit
命令更改堆栈进程的大小:
% cat main.adb
procedure Main is
type A_Type is abstract tagged null record;
type B_Type is new A_Type with null record;
type B_Type_Access is access all B_Type;
type C is array (1 .. 10_000_000) of B_Type_Access;
D : C;
begin
null;
end Main;
% gnatmake -gnato -gnata -fstack-check main.adb
[...]
使用足够的堆栈空间运行它:
% ulimit -s 90000
% ./main
% echo $?
0
% ulimit -s 9000
% ./main
raised STORAGE_ERROR : stack overflow (or erroneous memory access)
% echo $?
1
使用太小的堆栈空间运行它:
% ulimit -s 90000
% ./main
% echo $?
0
% ulimit -s 9000
% ./main
raised STORAGE_ERROR : stack overflow (or erroneous memory access)
% echo $?
1
使用GNAT,最好使用
-fstack check
进行构建。使用您的代码执行此操作会导致(在Mac OS X上)出现Storage\u错误
,并显示消息stack overflow
。在Linux上,如果不更改可执行文件的主堆栈大小,则其限制为8 MB。其他操作系统可能也有类似的限制。一个1000万地址的数组在32位上需要40 MB,在64位上需要80 MB。如果它是一个无约束的数组,我不能使用这个技巧,或者?我试过了,但没有成功。编辑:我可以。:-)