gpt4 book ai didi

arrays - Ada 中堆栈分配数组的访问类型

转载 作者:行者123 更新时间:2023-12-04 03:10:51 25 4
gpt4 key购买 nike

我正在尝试使用数组传递和访问类型做一些事情。我遇到过这样一种情况:嵌入式系统上的堆栈大小使得很难通过典型的参数传递机制传递大型数组。

为了节省堆栈大小,我已经开始使用访问类型,但我不想进行动态分配。

我所拥有的是这样的:

type My_Array_Type is array (Natural range<>) of Integer;
type My_Array_Type_Ptr is access all My_Array_Type;

procedure Do_Stuff(Things : My_Array_Type_Ptr) is
begin
-- things
end Do_Stuff;

procedure Do_Stuff(Num_Things : Integer) is
Things : My_Array_Type_Ptr := new My_Array_Type(1..Num_Things);
begin
Do_Stuff(Things);
-- more things
end Do_Stuff;


但是,我想做的是这样的:

type My_Array_Type is array (Natural range<>) of Integer;

procedure Do_Stuff(Things : access all My_Array_Type) is
begin
-- things
end Do_Stuff;

procedure Do_Stuff(Num_Things : Integer) is
Things : aliased My_Array_Type(1..Num_Things);
begin
Do_Stuff(Things'Access);
-- more things
end Do_Stuff;


但显然它不起作用。

本质上,我想传递对堆栈分配数组的引用并在另一个子程序中更改它,但我不想动态分配内存。我怎样才能做到这一点?

另外,作为旁注:我一直看到关于某些东西是否必须被释放而动态分配的冲突信息——我读到大多数实现没有垃圾收集器但不需要它们。任何人都可以澄清 - 在我首先展示的示例中,我是否需要明确取消分配?

编辑:
在尝试了下面提到的解决方案后,我决定将两件事结合起来:
  • 使用 in out参数传递机制。
  • 减少我的数据类型的存储要求。

  • 所以而不是 Integer我正在使用:
    type UInt8 is new Interfaces.Unsigned_8;

    这是:
    type UInt8 is mod 2**8
    with Size => 8;

    这很有效,因为我的值实际上不是整数,它们实际上是无符号字节。

    最佳答案

    在 Ada 中,您真的不需要在这种情况下使用访问类型。

    下面是原生 Ada 代码的备注;对于导入(我想是导出)子程序,生成的代码显然需要遵守外语约定。

    参数的模式(是否允许写入,是否(如果允许写入)是否具有某个初始值)与参数传递机制不同。

    如果您的参数大小大于寄存器并且参数传递机制不是通过引用(即通过传递实际对象的地址),请向您的编译器供应商投诉!

    Ada 的方式是这样的:

    with Ada.Text_IO; use Ada.Text_IO;
    with System.Storage_Elements;
    procedure Jsinglet is

    type My_Array_Type is array (Natural range<>) of Integer;

    procedure Do_Stuff_1 (Things : in out My_Array_Type) is
    begin
    Put_Line (System.Storage_Elements.To_Integer (Things'Address)'Img);
    end Do_Stuff_1;

    procedure Do_Stuff (Num_Things : Integer) is
    Things : My_Array_Type (1 .. Num_Things);
    begin
    Put_Line (System.Storage_Elements.To_Integer (Things'Address)'Img);
    Do_Stuff_1 (Things);
    end Do_Stuff;

    begin
    Do_Stuff (42);
    end Jsinglet;

    运行程序的结果在这里
    $ ./jsinglet 
    140732831549024
    140732831549024

    显示地址已通过,而不是值。
    in out模式开启 Do_Stuff_1的参数表示 Do_Stuff_1可以在写入之前读取传递给它的数组的内容。
    out将意味着 Do_Stuff_1不应该在它自己写入内容之前读取内容(它可以,但是 - 根据参数的类型 - 它可能读取未初始化或默认初始化的数据)
    in将意味着无法写入内容。

    关于arrays - Ada 中堆栈分配数组的访问类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59622362/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com