new
可以用于动态分配对象,但没有像delete
这样的关键字可以用于销毁它们的信息。在阅读《Ada 2012参考手册》中有关Ada.Unchecked_Deallocation
的提及时,我发现了一些有趣的摘录:
每个对象在被销毁之前都会被完成(例如通过离开包含对象声明的子程序体或调用Unchecked_Deallocation实例来实现)。
每个访问对象类型都有一个关联的存储池。分配器分配的存储来自该池; Unchecked_Deallocation的实例会返回存储到池中。
P用户定义的存储池对象的Deallocate过程可能会被实现调用,仅在允许P的Allocate调用的位置上为其池分配T类型的存储,在执行T的Unchecked_Deallocation实例期间,或作为集合T的终止的一部分来释放存储。
如果我要猜测,那就意味着当执行离开声明access的作用域时,与access相关联的对象可以被实现自动释放。无需显式调用Unchecked_Deallocation
。
这似乎得到了Ada 95质量和风格指南中的一节的支持,其中说明:
未经检查的存储器释放机制是覆盖回收分配存储器的默认时间的一种方法。最早的默认时间是当对象不再可访问时,例如,当控件离开访问类型声明作用域时(此后时间点依赖于实现)。在此之前执行任何未经检查的存储器释放可能会导致Ada程序错误,如果尝试访问对象。
但是措辞比较不清楚。如果我要运行这段代码,内存方面会发生什么事情呢?
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
procedure Run is
X : access Integer := new Integer'(64);
begin
Put (Integer'Image (X.all));
end Run;
begin
for I in 1 .. 16 loop
Run;
end loop;
end Main;
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
procedure Outer is
type Integer_Access is not null access Integer;
procedure Run is
Y : Integer_Access := new Integer'(64);
begin
Put (Integer'Image (Y.all));
end Run;
begin
for I in 1 .. 16 loop
Run;
end loop;
end Outer;
begin
Outer;
end Main;
是否有内存泄漏的保证,还是X
在Run
完成时被释放?
Finalize
过程,该过程在受控对象的任何组件最终化之前立即调用。”更多信息请参见上文。 - trashgod