【发布时间】:2021-07-11 21:00:56
【问题描述】:
我试图找到一些关于为什么关键字new 可用于动态分配对象的信息,但没有像delete 这样的关键字可用于释放它们。通过Ada 2012 参考手册中提到的Ada.Unchecked_Deallocation,我发现了一些有趣的摘录:
每个对象在被销毁之前都已完成(例如,通过 留下一个包含 object_declaration 的 subprogram_body,或者通过调用 Unchecked_Deallocation)
每个对象访问类型都有一个关联的存储池。分配器分配的存储空间来自 从游泳池; Unchecked_Deallocation 实例将存储返回到池中。
用户定义的存储池对象 P 的 Deallocate 过程可以由实现调用以 仅在允许对 P 进行分配调用的位置为池为 P 的类型 T 取消分配存储, 在执行 T 的 Unchecked_Deallocation 实例期间,或作为最终确定的一部分 T的集合。
如果我不得不猜测,这意味着当执行离开 access 的范围时,实现可以自动释放与 access 关联的对象em> 被声明。无需显式调用Unchecked_Deallocation。
a section in Ada 95 Quality and Style Guide 似乎支持这一点:
未经检查的存储释放机制是一种覆盖回收分配存储的默认时间的方法。最早的默认时间是对象不再可访问的时间,例如,当控制离开声明访问类型的范围时(此时间之后的确切时间取决于实现)。如果尝试访问该对象,则在此之前执行的任何未经检查的存储释放都可能导致错误的 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;
当Run 完成时,是否有保证的内存泄漏或X 被释放?
【问题讨论】:
标签: memory-management ada