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
aControlled
类型似乎不太可能,因为我无法从tubase
和Ada.Finalization.Controlled
中导出tufoo
,因为它们都不是接口类型
- 将
T_Base
定义为
类型T_Base是抽象的新Ada.Finalization.Controlled,带有空记录;
这里的overrideAdjust
似乎会对现有的代码库进行太多的修改,因为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
活页夹选项检查堆栈要求,我会对其中任何一个都失去信心。。。