Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用SetLength在Delphi中发生内存不足异常时释放内存_Delphi_Memory_Free_Multidimensional Array - Fatal编程技术网

如何使用SetLength在Delphi中发生内存不足异常时释放内存

如何使用SetLength在Delphi中发生内存不足异常时释放内存,delphi,memory,free,multidimensional-array,Delphi,Memory,Free,Multidimensional Array,我有一段Delphi代码 var a: array of array of array of integer; begin try SetLength(a, 100000, 100000, 10000); // out of memory here doStuffs(a); except a = nil; // try to free the memory end; end; 上面的代码试图分配大量内存,并且内存不足将被捕获。将执行a=nil,但不会释放内

我有一段Delphi代码

var
  a: array of array of array of integer;
begin
  try
   SetLength(a, 100000, 100000, 10000); // out of memory here
   doStuffs(a); 
  except
   a = nil; // try to free the memory 
  end;
end;
上面的代码试图分配大量内存,并且
内存不足
将被捕获。将执行
a=nil
,但不会释放内存

在出现内存不足异常的情况下,是否有办法释放内存


我尝试了
SetLength(a,0,0,0)
Finalize(a)
,但两者都不起作用。

一般来说,无法从内存不足错误中恢复。此时,堆很可能已损坏。适当的反应是终止该过程

在此特定情况下,分配由
系统
单元中的
DynArraySetLength
执行。这将执行重复分配。只有当
DynArraySetLength
的最后一个动作是返回值时,上面代码中的
a
才被实际赋值。如果在
DynArraySetLength
中发生错误,那么运行时将不进行整理。这意味着在发生故障的情况下,任何分配的内存都会泄漏,无法恢复。你没有办法参考它来释放它


您可能认为
DynArraySetLength
应该做更多的整理工作。然而,它的方法是合理的。由于内存不足的情况总是导致堆损坏,因此尝试清理只会延长痛苦。一旦堆死了,尝试释放内存就没有意义了。

接下来的自然问题是“有
TrySetLength
过程吗?”@AndreasRejbrand没有。你确定吗?它认为堆是否损坏取决于内存管理器内部。@Serg不适用于多维数组的SetLength。老实说,我不认为任何常用的彩信都能适应OOM。@AndreasRejbrand您可以创建这样一个函数,但是您需要编写自己的
DynArraySetLength
,以使其更加健壮。一个更简单(但不是竞争条件证明)的方法是检查内存是否可用,然后分配它。当您在异常处理程序中时,
A
甚至有一个非空值吗?如果没有,那么你很难期望能够释放它。此外,它将在函数结束时被释放。您是否确认
SetLength
在无法完成分配所有请求的内存时设置
a
变量?@Rob No,
a
在异常处理程序中为
nil
。是的,当代码进入异常块时,a=nil。PS:我使用FastMM作为内存管理器。在这种情况下,除非程序退出,否则内存不会被释放。