当前位置:编程学习 > 网站相关 >>

关于SetLength报Out of memory的研究及解决办法

关于SetLength报Out of memory的研究及解决办法
 
 
最近在做一个GIS系统, 在读GIS数据时采用了动态数组,突然读一个数据时SetLength报错!Out of memory
 
 
仔细研究了代码, 发现代码没有问题。问题应该动态数组的问题。
 
 
接下来查看各种资料,发现也有一些人发现了类似的问题,一般认为是频繁SetLength造成的,
具体为什么为造成错误呢?
我们来做一个测试
 
 
procedure TForm1.Button1Click(Sender: TObject);
var
     I,J  : Integer;
begin
     for I := 1 to 10 do  begin
          SetLength(giDatas,I*10);
          giDatas[I*10-1]   := I;
          //
          Memo1.Lines.Add(Format('I=%.2d, Addr = %d',[I,Integer(@giDatas[0])]));
     end;
end;
 
 
这个一段非常简单的代码,一般会认为@giDatas[0]会是定值(至少我以前是这样认为的)
 
 
I=01, Addr = 27139384
I=02, Addr = 26525640
I=03, Addr = 26525640
I=04, Addr = 26395448
I=05, Addr = 26395448
I=06, Addr = 26395448
I=07, Addr = 26395448
I=08, Addr = 26694280
I=09, Addr = 26694280
I=10, Addr = 26694280
 
 
根据得出的结果来看,@giDatas[0]在不断改变, 也就是giDatas在不断开辟新的内存
原来占用的内存没有及时释放,所以多次SetLength后会报Out of memory. 
 
 
问题找出来了, 解决办法还是问题。 仍然查找了许多资料, 发现用指针来解决
比如类似的程序
type
  duilie=record
     item_name:integer;
     level:integer;
     count:integer;
     father:integer;
     children:array of integer;
  end;
var 
  leaf:array of duilie;
 
 
其中leaf的定义采用
type
     Pduilie = ^duilie;
var
    leaf:array of pduilie; 
应该就可以了
 
 
补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,