memory-management - 当内存被释放时,Ada 中会发生什么?

我对Ada 完全陌生,我必须为我在学校上的一门课程学习它。

我做过的一个练习要求一个程序交换指针的地址,然后将打印机的地址更改为另一个,并释放以前的地址。

正如您在下一个示例中看到的那样,我正在做需要做的事情,但我很好奇当它被释放时该地址发生了什么,通过持有对它的引用,并意识到它在其中放入了垃圾,我'我猜测该地址中的标志发生了变化,并且告诉编译器该内存地址已被释放,我只是不确定,也无法在网上找到表明我的假设是否正确的内容。

procedure Main is
   type T_Pointer is access Integer;
   I, J, aux: T_Pointer;
   
   procedure FreeMemoryAddress is new Unchecked_Deallocation(integer, T_Pointer);
   
   procedure ChangePointerAddress(Origen: in out T_Pointer; destino: in T_Pointer);
   
   procedure ChangePointerAddress(Origen: in out T_Pointer; destino: in T_Pointer)
   is
   begin
      origen:=destino;
   end ChangePointerAddress;

   procedure SwapPointers (I, J: in out T_Pointer);

   procedure SwapPointers (I, J: in out T_Pointer)
   is
      aux: T_Pointer;
   begin
      aux := new Integer;
      Aux := I;
      I:=J;
      J:=Aux;

   end SwapPointers;


begin

   I:=new Integer;
   J:=new Integer;

   Put_Line("i's uninitialized value: " & integer'Image(I.all));


   Put_Line("i's address: " & System.Address_Image(I.all'Address));
   Put_Line("j's address: " & System.Address_Image(j.all'Address));


   SwapPointers(I, J);
   Put_Line("After swapping:");
   Put_Line("i's address: " & System.Address_Image(I.all'Address));
   Put_Line("j's address: " & System.Address_Image(j.all'Address));
   
   aux:=j;
   FreeMemoryAddress(j);
   Put_Line("aux's value: " & Integer'Image(aux.all)); --garbage
   Put_Line("aux's address: " & System.Address_Image(aux.all'Address));

end Main;

回答1

Ada 中的memory management 的某些方面在https://stackoverflow.com/q/67131931/230513 进行了概述。在 https://www.adaic.org/resources/add_content/standards/12rm/html/RM-13-11-2.html 的特殊情况下,该标准建议实例“实际上应该回收存储”。正如@Simon Wright https://stackoverflow.com/a/72301614/230513,释放细节可能是特定于实现的——标记、归零或毒化释放的内存——取决于主机操作系统。 MacOS,对于https://apple.stackexchange.com/questions/425778/does-macos-automatically-erase-freed-memory-to-prevent-leakage-of-information-l,使用了几种这样的安全相关策略;您可能想研究您的操作系统。

在下面的变体中,我添加了一个 Default_Value 方面和代码,以在被释放之前和之后显示 J 的 value。尝试在调用后引用 J.all 的 value 以查看尝试取消引用 null 引发的错误。

Before Free (J):
J value: -1
J address: 000060000085C030
After Free (J):
J value:  756334640
J address: 000060000085C030

代码:

with Ada.Text_IO;                use Ada.Text_IO;
with Ada.Unchecked_Deallocation; use Ada;
with System.Address_Image;       use System;

procedure Main is
   type Int is new Integer with Default_Value => -1;
   type Int_Ptr is access Int;
   I, J, Temp : Int_Ptr;

   procedure Free is new Unchecked_Deallocation (Int, Int_Ptr);

   procedure SwapPointers (I, J : in out Int_Ptr) is
      Aux : Int_Ptr := new Int;
   begin
      Aux := I;
      I   := J;
      J   := Aux;
   end SwapPointers;

begin
   I := new Int;
   J := new Int;
   Put_Line ("I & J values: " & Int'Image (I.all) & " " & Int'Image (J.all));
   Put_Line ("I address: " & Address_Image (I.all'Address));
   Put_Line ("J address: " & Address_Image (J.all'Address));
   SwapPointers (I, J);
   Put_Line ("After swapping:");
   Put_Line ("I address: " & Address_Image (I.all'Address));
   Put_Line ("J address: " & Address_Image (J.all'Address));

   Put_Line ("Before Free (J):");
   Put_Line ("J value: " & Int'Image (J.all));
   Put_Line ("J address: " & Address_Image (J.all'Address));
   Temp := J;
   Free (J);
   Put_Line ("After Free (J):");
   Put_Line ("J value: " & Int'Image (Temp.all)); --garbage
   Put_Line ("J address: " & Address_Image (Temp.all'Address));
end Main;

回答2

看到 I.all 的初始 value 为 0,我有点惊讶,因为编译器不需要确保已初始化分配的内存(至少,http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-4-8.html#p9 表示“分配了任何隐式初始 value”,请参阅 http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-3-3-1.html#p10,此处都不是这种情况)。 VxWorks 5.3 的 GNAT 过去不初始化分配的数据,这让那些在 Windows 上开发的人在迁移到 VxWorks 目标时感到惊讶;我们制作了自己版本的内存分配器 (s-memory.adb),它用 16#deadbeef# 填充内存。

我们的分配器还使用类似但不同的模式(16#feebdaed#? - 不久前)填充了已释放的内存。

在 macOS 上,可能在这种情况下,GNAT 内存释放器调用 C free(),它会做任何事情。返回的内存可能会在将其重新链接到系统内存区域时被覆盖,和/或立即重用,例如通过您的 post-Free 代码。

相似文章

task - 任务:非常缓慢的响应

我的实际程序创建了一个task,我不会对控制消息做出应有的反应。由于它已经变得相当大,我提出了一个具有相同控制逻辑的简短测试程序。它创建了一个背景task,它每0.1秒重复一个循环。根据受保护的标志“...

最新文章