我的代码如下:type
  TLeafNode =record                                          
    VOPC: String;        
    COED: array[1..4] of string;          
    VOPA: array of array of array of array of real;                       
  end;
  TPLeafNode = ^TLeafNode;procedure TForm1.Button1Click(Sender: TObject);
var
  Lp: TPLeafNode;
  i: Integer;
begin
  for i:=1 to 1000 do
  begin
    LP:=AllocMem(Sizeof(TLeafNode));
    SetLength(LP.VOPA,1000,1000,1000,1000);
    LP.VOPA:=nil;
    FreeMem(LP,Sizeof(TLeafNode));
  end;
end;结果记录的内存没有释放掉,经过大约几百次循环,最后内存溢出。
请问怎么样才能把我申请的记录和记录中的那个四维动态数组释放掉?

解决方案 »

  1.   

    procedure TForm1.Button1Click(Sender: TObject);
    var
      Lp: TPLeafNode;
      i: Integer;
    begin
      for i:=1 to 1000 do
      begin
        LP:=AllocMem(Sizeof(TLeafNode));
        SetLength(LP.VOPA,1000,1000,1000,1000);
        FreeMem(LP.VOPA);
      end;
    end;
      

  2.   

    这样试试吧.应是LP.VOPA指向的内存没释放的原因.
      

  3.   

    procedure TForm1.Button1Click(Sender: TObject);
    var
      Lp: TPLeafNode;
      i: Integer;
    begin
      for i:=1 to 1000 do
      begin
        LP:=AllocMem(Sizeof(TLeafNode));
        SetLength(LP.VOPA,1000,1000,1000,1000);
        FreeMem(LP.VOPA);
        FreeMem(Lp);
      end;
    end;
      

  4.   

    to pankun(剑神一笑 ^_^) :
    可以说,肯定是那个四维数组没有释放,我试了一下,使用FreeMem(LP.VOPA)也不能解决内存增长问题。不知道怎么回事。
      

  5.   

    SetLength(LP.VOPA, 0, 0, 0, 0);
    LP.VOPA := nil;试试?
      

  6.   

    你在setlength后有让LP.VOPA:=nil;,那你说你怎么让计算机释放呢?
      

  7.   

    其实赋值和释放是放在两个不同的函数里,我是为了实验才把它们写在一起。
    我有一个指针数组 VHPA:Array of TPLeafNode;
    因为需要不停的创建TleafNode类型的记录来存放数据库中的值(维数比较大),所以在使用完记录后需要释放,我使用上面我所说的释放方法,结果没运行几次循环就溢出了。
      

  8.   

    用SetLength把长度设为0还是不行啊?
      

  9.   

    我是使用MemProof监视程序使用的内存,它还是‘呼呼’的长!   苦~~
      

  10.   

    按理不应该有问题啊
    你用这个试试呢?
      Finalize(Lp.VOPA);
      

  11.   

    我以前做项目时也到过,这种不停的申请和释放的内存确实会引起内存的泄漏,我用的是
    new dispose
      

  12.   

    我也试图找过答案也找不到,就是觉得这种动态申请和释放内存不安全,后来我改为用tstringlist自己写了个内存表控件,当然也可以用tclientdataset做内存表
      

  13.   

    我用C++试了一下----其实根本没办法试:
    for (i=0;i<1000;i++)
    {  
      lp = NULL;
      lp = (PTLeafNode)malloc(sizeof(double)*1000*1000*1000*1000);
      if (lp ==NULL )//系统无法为lp分配内存,太大了,953674兆,不予理睬,直接break
      {
        MessageBox (NULL, TEXT ("Out of memory"), TEXT("123"), MB_ICONERROR) ;
        break;
      }
      free(lp);
    }另外,我转换的原理应该没错吧?
      

  14.   

    FreeMem(LP.VOPA);
        FreeMem(Lp);
      

  15.   

    SetLength(LP.VOPA,1000,1000,1000,1000);
        LP.VOPA:=nil;这句后面让LP.VOPA:=nil;所以没有释放。
      

  16.   

    你写的语句有问题:
    把LP:=AllocMem(Sizeof(TLeafNode));放到循环外面
      

  17.   

    还有,你的循环没有意义,因为动态数组的重新定义和I没有关系,你只是在内存中为LP.VOPA
    分配了i个(1000,1000,1000,1000)大小的空间。
      

  18.   

    如果确实想这样做的话:就在每次循环的过程最后,用function ReAllocMem(P:Pointer;CurSize,NewSize:Cardinal):Pointer;来释放堆。
      

  19.   

    计算函数function Caculation(T:TPTwigNode): Pointer;
    var
      i,j: integer;
      RA: Array of Integer;
      LP: TPLeafNode;
      Str1,Str2: String;
    begin
      {结果记录初始化}
      
      SetLength(RA,4);
      LP:=TPLeafNode(NodeCreate(Sizeof(TLeafNode)));
      RA[0]:=0; RA[1]:=0; RA[2]:=0; RA[3]:=0;  for i:=Low(TPSetNode(T.MCP).Data) to High(TPSetNode(T.MCP).Data) do
      begin
        if (RA[0]<TPSetNode(T.MCP).Data[i][0]) then RA[0]:=TPSetNode(T.MCP).Data[i][0];
        if (RA[1]<TPSetNode(T.MCP).Data[i][1]) then RA[1]:=TPSetNode(T.MCP).Data[i][1];
        if (RA[2]<TPSetNode(T.MCP).Data[i][2]) then RA[2]:=TPSetNode(T.MCP).Data[i][2];
        if (RA[3]<TPSetNode(T.MCP).Data[i][3]) then RA[3]:=TPSetNode(T.MCP).Data[i][3];
      end;  SetLength(LP.VOPA,RA[0]+1,RA[1]+1,RA[2]+1,RA[3]+1);  for i:=Low(TPSetNode(T.MCP).CS) to High(TPSetNode(T.MCP).CS) do
        LP.COED[i]:=TPSetNode(T.MCP).CS[i];  if (T.OS='S')  then            //累加或连乘运算
      begin
        for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
          LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
            LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]+
            TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]];   //显示检查
     {   for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
        begin
          for j:=Low(TPSetNode(T.PLSet).Data[i]) to High(TPSetNode(T.PLSet).Data[i]) do
          begin
            Str1:=Str1+'  '+FloatToStr(TPSetNode(T.MCP).Data[i][j]);
            Str2:=Str2+'  '+FloatToStr(TPSetNode(T.PLSet).Data[i][j]);
          end;
          FrmCaculation.Memo1.Lines.Add(' ');
          FrmCaculation.Memo1.Lines.Add('MCP:  '+Str1);
          FrmCaculation.Memo1.Lines.Add('MLP:  '+Str2);
          Str1:=''; Str2:='';
        end;    }
      end
      else if (T.OS='P') then
      begin
        for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
          LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
            LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]*
            TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]];
      end
      else if (T.RCP=nil)and(T.PRValue=nil)and(T.PRSet=nil) then  //单目运算
      begin
        if T.OS='sin' then
          for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
            LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
              sin(TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]);
        if T.OS='cos' then
          for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
            LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
              cos(TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]);
        if T.OS='tan' then
          for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
            LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
              Tan(TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]);
        if T.OS='exp' then
          for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
            LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
              exp(TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]);  end
      

  20.   

    else  // 双目运算
      begin
        if T.OS='+' then
          for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
            LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
              TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]+
              TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]];    if T.OS='-' then
          for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
            LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
              TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]-
              TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]];    if T.OS='*' then
          for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
            LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
              TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]*
              TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]];    if T.OS='/' then
          for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
            LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
              TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]/
              TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]];    if T.OS='^' then
          for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
            LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
              POWER(TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]],
              TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]]);
                        
        if T.OS='>' then
          for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
            if (TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]>
              TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]]) then
              LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=1
            else LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=0;    if T.OS='<' then
          for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
            if (TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]<
              TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]]) then
              LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=1
            else LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=0;    if T.OS='=' then
          for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
            if (TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]=
              TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]]) then
              LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=1
            else LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=0;  end;
      Result:=LP;
    end;
      

  21.   


    二叉树的后序遍历function BinaryTreePostOrderTraverse(T:TPTwigNode): Pointer;
    var S: Array of stackelement;
       Top: Integer;
       Root: TPTwigNode;
    begin
      SetLength(S,255);
      Top:=0;
      Root:=T;       //保存根指针
      while (T<>nil) or (top<>0) do
      begin
        while T<>nil do
        begin
          INC(top,1);
          S[top].T:=T;
          S[top].tag:=0;
          T:=T.LCP;
        end;
        while (top<>0) and (s[top].tag=1) do
        begin
          if S[top].T.FP<>nil then
            if S[top].T.FPF='Left' then
            begin
              if TPTwigNode(S[top].T.FP).PLValue<>nil then NodeFree(TPLeafNode(TPTwigNode(S[top].T.FP).PLValue));//如果存在旧结果则释放
                TPTwigNode(S[top].T.FP).PLValue:=Caculation(S[top].T);
            end
            else if S[top].T.FPF='Right' then
            begin
              if TPTwigNode(S[top].T.FP).PRValue<>nil then NodeFree(TPLeafNode(TPTwigNode(S[top].T.FP).PRValue));//如果存在旧结果则释放
                TPTwigNode(S[top].T.FP).PRValue:=Caculation(S[top].T);
            end
            else showmessage('二叉树生成:头指针标志赋值错误');
          Dec(top,1);
        end;
        if top<>0 then
        begin
          S[top].tag:=1;
          T:=S[top].T.RCP;
        end;
      end;
      S:=nil;
      Result:= Caculation(Root);
    end;实验函数:
    procedure TFrmCaculation.Button18Click(Sender: TObject);
    var i, j:Integer;
        RP: TPLeafNode;
    begin
      j:=StrToInt(Edit2.Text);
      for i:=0 to j do
      begin
        RP:=TPLeafNode(BinaryTreePostOrderTraverse(P));
        RP.VOPA:=nil;
        FreeMem(RP);
      end;
    end;实验:重复调用二叉树计算,看内存变化。
    然后在Edit2中填入5000,点Button18,内存每秒长大约16K,我实在找不出问题,只好求求大家看看。
      

  22.   

    个人认为:
    1,record的结构不是很良好,一般情况下,record的结构尽量使用基本类型,如果存在array of array of....等,最好将array of 再用一个结构封装
    2,对应String的释放问题。delphi的string的管理其实是一个指针。这里我建议将array[1..4] of string;  换成:array [0..3] of pchar,而后动态的给pchar分配内存。这样可以确定保证没有内存泄漏。
    3,对于复杂的record,可以使用类来代替,这样,对于内存的管理可以统一操作
    4,使用boundercheck for delphi可以检查到你的内存什么地方没有处理:)
      

  23.   

    boundercheck???哪儿下载???
    我使的是MemProof,来监视内存。