Ada 多态类型的函数参数的深度副本

Ada 多态类型的函数参数的深度副本,ada,Ada,我使用基于基本包的对象,大致定义如下: 包基础是 类型T_Base是抽象标记的空记录; --这将执行深度复制。浅拷贝可能导致存储错误。 --这应通过每个派生类型实现。 函数复制(From:in T_Base)返回T_Base'Class是抽象的; 端部封装基座; 这个包是由几个包派生的,这些包是进一步派生的 包Foo是 类型T_Foo是带有记录的新T_基 A_数据:自然;——当然,在实际代码中,这些类型要复杂得多。 结束记录; 过程做某事(Foo\u对象:在T\u Foo中); --这实现了深

我使用基于基本包的对象,大致定义如下:

包基础是
类型T_Base是抽象标记的空记录;
--这将执行深度复制。浅拷贝可能导致存储错误。
--这应通过每个派生类型实现。
函数复制(From:in T_Base)返回T_Base'Class是抽象的;
端部封装基座;
这个包是由几个包派生的,这些包是进一步派生的

包Foo是
类型T_Foo是带有记录的新T_基
A_数据:自然;——当然,在实际代码中,这些类型要复杂得多。
结束记录;
过程做某事(Foo\u对象:在T\u Foo中);
--这实现了深度复制
函数复制(From:in T_Foo)返回T_基类是抽象的;
结束包Foo;
调用过程
do\u something
,我确实收到一个
storage\u错误

procedure handle\u received\u foo(foo\u In:In foo.T\u foo)是
开始
Foo.do_something(Foo_Object=>Foo_In);--存储错误确实发生在这里。
端干管;
当使用gdb运行代码时,我在输入函数时得到一个segfault,我得到:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 39 (LWP 39)]
0x033c9828 in foo.do_something (foo_object=...) at ./foo.adb:67
67         procedure do_something (Foo_Object : in T_Foo);
(gdb) p foo_object
$1 (null)
因此,我猜在执行参数
Foo\u对象的浅拷贝时,会出现
storage\u错误

我知道这不是MWE,并且在派生类型中使用的一个类型中可能存在错误

我找不到任何好的选择:

  • Adjust
    中调用
    Copy
    调用
    Adjust
    中的
    tufoo
    a
    Controlled
    类型似乎不太可能,因为我无法从
    tubase
    Ada.Finalization.Controlled
    中导出
    tufoo
    ,因为它们都不是接口类型

  • T_Base
    定义为

    类型T_Base是抽象的新Ada.Finalization.Controlled,带有空记录;
    
    这里的override
    Adjust
    似乎会对现有的代码库进行太多的修改,因为gnat在多个地方产生

    具有私有祖先“受控”的聚合类型必须使用扩展聚合


因此,我缺乏进一步调查问题或用锤子解决问题的解决方案。

问题不在
复制功能中。我在代码库中看到的评论具有误导性

由于引入新的变量改变了异常的位置,所以我考虑了一些堆栈溢出问题。 实际上,分配给任务的
存储大小
是不够的。增加
pragma存储大小()
解决了这个问题

由于代码库是使用
-fstack check
编译的,因此会导致前面提到的
存储错误

更多信息


这可能已经在中看到,但我目前无法看到其中建议的绑定选项的任何结果。

如何将T_FOO传递到主程序?如果main有一个本地声明并正确初始化的T_FOO,dou something调用是否有效?我通过网络获取T_FOO。它确实不在我的主程序中(对不起,本不应调用此主程序)。T_Foo比示例中的要复杂得多。但我想我可以比较这种类型的深层和浅层拷贝,看看它们是否会产生存储错误。我没有看到任何调用
Copy
。就目前的情况来看,您似乎正在将
null
传递给
Foo。做点什么吧
——不确定这是怎么发生的我可能完全走上了错误的轨道。在代码上花一点时间研究副本会导致存储错误。我考虑的问题源于存储大小太小,“对于任务,存储大小子句指定要分配给任务堆栈的空间量。这不能扩展,如果堆栈耗尽,则会引发存储错误(如果启用堆栈检查)。”在我的情况下“-fstack check”已启用…如果您没有使用
-fstack check
,而不是
Storage\u Error
,您可能很快就会看到操作系统出现segfault。我最糟糕的记忆是跟踪导致这两种情况之一的bug……我同意,由于
-fstack check
而“更早”看到bug会使调试更容易。然而,当gdb用
info tasks
告诉我有大约50个任务正在运行时,如果不能用
-u
活页夹选项检查堆栈要求,我会对其中任何一个都失去信心。。。