如何在Ada中使用'多维数组的最后一个属性?

时间:2012-04-04 19:40:34

标签: arrays multidimensional-array ada

我试图在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。

3 个答案:

答案 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>


我在想一个默认值。 (当我感觉不舒服时,可能不应该发帖: - )