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

jsi*_*let 3 arrays ada

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

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

我所拥有的是这样的:

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;

Run Code Online (Sandbox Code Playgroud)

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

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;

Run Code Online (Sandbox Code Playgroud)

但显然它不起作用。

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

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

编辑:在尝试了下面提到的解决方案后,我决定结合两件事:

  1. 使用in out参数传递机制。
  2. 减少我的数据类型的存储要求。

所以而不是Integer我使用:

type UInt8 is new Interfaces.Unsigned_8;
Run Code Online (Sandbox Code Playgroud)

这是:

type UInt8 is mod 2**8
     with Size => 8;
Run Code Online (Sandbox Code Playgroud)

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

Sim*_*ght 6

在 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;
Run Code Online (Sandbox Code Playgroud)

运行程序的结果在这里

$ ./jsinglet 
 140732831549024
 140732831549024
Run Code Online (Sandbox Code Playgroud)

显示地址已通过,而不是值。

in out接通模式Do_Stuff_1的参数单元,其Do_Stuff_1可以在写入之前读取传递给它的数组的内容。

out这意味着Do_Stuff_1在它自己写入内容之前不应该读取内容(它可以,但是 - 根据参数的类型 - 它可能会读取未初始化或默认初始化的数据)

in 将意味着无法写入内容。

  • 当我尝试使用“Unchecked_Conversion”将“this”数组转换为“that”数组时遇到问题。但UC实际上制作了副本! (2认同)
  • 我想让您知道我能够通过结合使用上述技术并将数据类型更改为更小来解决我的问题。这似乎解决了我的问题。 (2认同)