用于初始化动态分配数组的 Ada 语法
Ada Syntax for initializing dynamically allocated array
在 Ada 中初始化动态分配数组的正确语法是什么?我试过这个:
type Short_Array is array (Natural range <>) of Short;
Items : access Short_Array;
Items := new Short_Array(1..UpperBound)'(others => 0);
这会导致编译器错误 - "binary operator expected"。还有这个:
type Short_Array is array (Natural range <>) of Short;
Items : access Short_Array;
Items := new Short_Array(1..UpperBound);
Items.all := (others => 0);
这似乎令人惊讶地引发了 SEGFAULT。不确定那里发生了什么,但想在开始追尾之前获得正确的语法。
如果您使用的是 Ada2012,您可以执行以下操作:
type Short_Array is array(Natural range <>) of Short with
Default_Component_Value => 0;
Items : access Short_Array := new Short_Array(1..UpperBound);
Ada 2012 基本原理第 2.6 节解释了数组默认初始值的使用 http://www.ada-auth.org/standards/12rat/html/Rat12-2-6.html
Ada 中的另一种方法是将记录定义为判别式记录,判别式决定数组字段的大小。
type Items_Record (Size : Natural) is record
-- Some non-array fields of your record
Items : Short_Array(1..Size);
end record;
然后可以在内部块中分配记录的实例
Get(Items_Size);
declare
My_Record : Items_Record(Size => Items_Size);
begin
-- Process the instance of Items_Record
end;
记录是在堆栈上动态分配的。如果记录大小非常大,您将遇到堆栈溢出问题。如果没有,这很好用。这种方法的一个优点是,当到达块末尾时,实例会自动取消分配。
第二个示例中的 SEGFAULT
肯定来自初始化。
比较
type Short_Array is array (Natural range <>) of Short;
Items : access Short_Array;
Items := new Short_Array(1..UpperBound);
Items.all := (others => 0);
还有这个:
type Short_Array is array (Natural range <>) of Short;
Items : access Short_Array;
Items := new Short_Array(1..UpperBound);
for I in 1..UpperBound loop
Items(I) := 0;
end loop;
并使用不同的 ulimit -Ss
值来设置允许的堆栈大小。
重点是
Items.all := (others => 0);
在堆栈上分配一个数组并将其复制到堆分配的数组中。所以你认为你在堆上工作但仍然需要很多堆栈。如果你的数组对于你的 ulimit -Ss
来说太大了(或者考虑到软限制和硬限制 ulimit -s
),你会出现段错误(或者得到一个 STORAGE_ERROR
),尽管你认为你都在堆上.
为了缓解这个问题,(虽然它可能不是在所有情况下都有效,例如如果UpperBound
是动态的......),你可以编译你的代码:
"-fstack-usage"
(获取每个单元的使用信息)
"-Wstack-usage=2000"
(或对您的情况更准确的任何限制,请参阅 gnat's documentation 了解更多信息)以对使用过多堆栈(或无限堆栈使用)的函数发出警告。
第二个选项可能会发出警告并指出您的堆栈溢出。
在 Ada 中初始化动态分配数组的正确语法是什么?我试过这个:
type Short_Array is array (Natural range <>) of Short;
Items : access Short_Array;
Items := new Short_Array(1..UpperBound)'(others => 0);
这会导致编译器错误 - "binary operator expected"。还有这个:
type Short_Array is array (Natural range <>) of Short;
Items : access Short_Array;
Items := new Short_Array(1..UpperBound);
Items.all := (others => 0);
这似乎令人惊讶地引发了 SEGFAULT。不确定那里发生了什么,但想在开始追尾之前获得正确的语法。
如果您使用的是 Ada2012,您可以执行以下操作:
type Short_Array is array(Natural range <>) of Short with
Default_Component_Value => 0;
Items : access Short_Array := new Short_Array(1..UpperBound);
Ada 2012 基本原理第 2.6 节解释了数组默认初始值的使用 http://www.ada-auth.org/standards/12rat/html/Rat12-2-6.html
Ada 中的另一种方法是将记录定义为判别式记录,判别式决定数组字段的大小。
type Items_Record (Size : Natural) is record
-- Some non-array fields of your record
Items : Short_Array(1..Size);
end record;
然后可以在内部块中分配记录的实例
Get(Items_Size);
declare
My_Record : Items_Record(Size => Items_Size);
begin
-- Process the instance of Items_Record
end;
记录是在堆栈上动态分配的。如果记录大小非常大,您将遇到堆栈溢出问题。如果没有,这很好用。这种方法的一个优点是,当到达块末尾时,实例会自动取消分配。
第二个示例中的 SEGFAULT
肯定来自初始化。
比较
type Short_Array is array (Natural range <>) of Short;
Items : access Short_Array;
Items := new Short_Array(1..UpperBound);
Items.all := (others => 0);
还有这个:
type Short_Array is array (Natural range <>) of Short;
Items : access Short_Array;
Items := new Short_Array(1..UpperBound);
for I in 1..UpperBound loop
Items(I) := 0;
end loop;
并使用不同的 ulimit -Ss
值来设置允许的堆栈大小。
重点是
Items.all := (others => 0);
在堆栈上分配一个数组并将其复制到堆分配的数组中。所以你认为你在堆上工作但仍然需要很多堆栈。如果你的数组对于你的 ulimit -Ss
来说太大了(或者考虑到软限制和硬限制 ulimit -s
),你会出现段错误(或者得到一个 STORAGE_ERROR
),尽管你认为你都在堆上.
为了缓解这个问题,(虽然它可能不是在所有情况下都有效,例如如果UpperBound
是动态的......),你可以编译你的代码:
"-fstack-usage"
(获取每个单元的使用信息)"-Wstack-usage=2000"
(或对您的情况更准确的任何限制,请参阅 gnat's documentation 了解更多信息)以对使用过多堆栈(或无限堆栈使用)的函数发出警告。
第二个选项可能会发出警告并指出您的堆栈溢出。