EXCEPTION_ACCESS_VIOLATION 静态声明

EXCEPTION_ACCESS_VIOLATION on a static declaration

我是 for ***'Address use *** 的新手。我想知道这种用法的局限性是什么。所以我创建了以下过程:

procedure letshack (A : System.Address) is 
      My_String : String(1..100000);
      for My_String'Address use A;
   begin 
      Put(My_String);
   end;

这会引发 EXCEPTION_ACCESS_VIOLATION 而具有 100 长度字符串的相同代码不会引发它。此外,如果我不使用整数地址,则此代码可以正常工作。

那么for ***'Address use ***使用的限制是什么。 Ps : 我正在使用 Ada 95,但欢迎提供任何信息。

编辑: 我理解部分行为。这就是我的假设。 当您启动程序时,会分配一个特定的堆栈,您可以在其中写入和读取。事实上,我用整数地址写了第 5 个字节

Real Addresses |----------------------------| Virtual Addresses
        0x48000|Stack Origine               |0x00
               |                            |
               |                            |
               |                            |
               |                            |
               |End of Stack                |
  0x48000+range|----------------------------|0x00+range

如果你没有堆栈,你会得到 EXCEPTION_ACCESS_VIOLATION。如果是对的,"strong" 语言似乎很奇怪。因为这意味着您可以重写自己的堆栈并做出不良行为。

如果您确保在从 A 开始的内存可读部分分配了 100_000 个连续字符,那么它应该可以工作。

如果 A 是另一个 Ada 实体的地址,则它不应该工作。

终于找到了行为。 当您启动程序时,您使用的地址是页面中的虚拟地址。 系统中处理虚拟地址的部分为分配给您的进程的一定大小的内存提供了空间,这取决于您的系统,如以下模式所示:

Real Addresses |----------------------------| Virtual Addresses
        0x48000|Begin of the virtual address|0x00
               |range                       |
               |                            |
               |                            |
               |End of the virtual address  |
               |range                       |
  0x48000+range|----------------------------|0x00+range

你可以做任何事情而无需在其中分配变量。例如,在我的 windows 上,根据 <windows.h> 中的变量 si.dwPageSize,这个大小是 4096 bytes。 我测试了我的字符串可以是 4096 字节长但不是 4097 字节。我现在必须在我的嵌入式系统上测试它,但似乎接近事实。