有没有办法让这段代码有效?我想创建一个大小为10mio的数组。地址。但是运行此代码会引发* CONSTRAINT_ERROR:错误的内存访问*。
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;
答案 0 :(得分:4)
我猜测堆栈中变量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;
答案 1 :(得分:2)
Herr_Doktor有一个很好的解决方案。另一个是将数组(和所有类型)放在一个包中(我假设Main
不会递归调用自身):
package Main_Package is
procedure Main;
end Main_Package;
package body Main_Package 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;
procedure Main is
begin
-- whatever you were going to do
end Main;
end Main_Package;
with Main_Package;
procedure Main is
begin
Main_Package.Main;
end Main;
现在,由于数组C
不再在一个过程中,它将被分配在常规数据存储器而不是堆栈中。
答案 2 :(得分:1)
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