我试图在Ada中使用带有2D数组的'Last
属性,但我似乎无法找到正确的语法。
我知道如果我有一维数组/向量,我可以使用A'last或A'last(n),其中n是第n维。但如果我做以下
type UnconstrainedArray_2D is array (Integer range <>, Integer range <>) of Integer;
function temp(tempIn : in Integer;
Table : in UnconstrainedArray_2D) return Integer is
tempTable : UnconstrainedArray_2D(0..tempIn, 0..tempIn);
begin
for i in 0..tempTable'last(1) loop
for j in 0..tempTable'last(2) loop
tempTable(i, j) := Table(i,j);
end loop;
end loop;
end temp;
我收到以下编译时错误:
Storage_Error堆栈溢出(或错误的内存访问)
那么我做错了什么?
我在Linux上使用GNAT Pro 6.4.1。
答案 0 :(得分:3)
如果您对该代码有编译时 Storage_Error
,我会感到非常惊讶。
我抓住了你的代码副本并修改如下;使用GNAT(gcc-4.4)编译时没有错误:
procedure Array_2D is
type UnconstrainedArray_2D is array (Integer range <>, Integer range <>) of Integer;
function temp(tempIn : in Integer;
Table : in UnconstrainedArray_2D) return Integer is
tempTable : UnconstrainedArray_2D(0..tempIn, 0..tempIn);
begin
for i in 0..tempTable'last(1) loop
for j in 0..tempTable'last(2) loop
tempTable(i, j) := Table(i,j);
end loop;
end loop;
return 42; -- added this
end temp;
begin
null;
end Array_2D;
(请注意,我必须在return
中添加缺少的temp
语句。)
'Last
属性(不是“命令”)的语法是正确的,但由于Ada数组可以具有任意的上限和下限,因此最好使用'Range
属性:
for i in tempTable'Range(1) loop
for j in tempTable'Range(2) loop
tempTable(i, j) := Table(i,j);
end loop;
end loop;
对于Storage_Error
异常,如果您为{temp
函数调用{{1>}函数的值非常大,那么这很容易在运行时发生(不编译时) 1}}。请记住,它必须分配足够的空间来容纳tempIn
tempIn**2
个对象。据推测,您还创建了另一个Integer
对象作为UnconstrainedArray_2D
参数传入。
可以想象编译器本身可能会因Table
异常而死,但我在代码中看不到任何可能导致此异常的内容。
向我们展示一个完整的(但很小的)程序,它可以演示您遇到的问题以及确切的(复制并粘贴)错误消息。请清楚地区分编译时错误和运行时错误。
答案 1 :(得分:2)
您的tempTable
可能有0..tempIn
的范围,但您不知道Table
的范围。它们的长度可能不同。
您必须检查长度是否相同,然后使用相对索引,如下所示:
function temp(tempIn : in Integer;
Table : in UnconstrainedArray_2D) return Integer is
tempTable : UnconstrainedArray_2D(0..tempIn, 0..tempIn);
begin
if tempTable'Length (1) /= Table'Length (1) or else
tempTable'Length (2) /= Table'Length (2)
then
raise Constraint_Error; -- or something else
end if;
for i in 0 .. tempTable'Length (1) - 1 loop
for j in 0 .. tempTable'Length (2) - 1 loop
tempTable(tempTable'First (1) + i, tempTable'First (2) + j) :=
Table(Table'First (1) + i, Table'First (2) + j);
end loop;
end loop;
end temp;
这样可确保两个表的长度相同且所有索引都有效。
如果允许tempTable
小于Table
,只需将长度检查调整为>
即可。指数仍然有效。
答案 2 :(得分:0)
我没有看到 tempIn 设置的实际值。如果未正确初始化或明确设置进入函数temp的 tempIn 的值,则 tempIn 中的值可能是任何值,可能不是您想要的值。< / p>
我在想一个默认值。 (当我感觉不舒服时,可能不应该发帖: - )