• 动态数组 && 释放问题


    理论上,数组的容器就是进程,关闭程序,数组的那块才会释放掉。不像类(如窗体上的的按钮设置了容器即parent,它放在谁的上面,谁在释放之前就会把按钮先释放掉),类的对象有parent、owner这两个的一个就会跟着parent或者owner释放而释放。

    直接释放一维会造成内存泄露。setlength了几次就要释放几次!第一个setlength是一维给了一次,二维又setlength给了一次,释放就反过来,先把二维释放,再释放一维。怎么给的空间,就怎么把空间释放掉,不要给程序留下隐患。

    但是,测试发现,先释放二维再释放一维与直接释放一维,这二者的效果是一样的(看下面代码的最后2个button的过程代码即可)!!以后对于多维数组的释放问题,直接释放一维数组即可!

    释放动态数组可使用下面这3种方式,都可以实现:

    SetLength(Myarray,0);
    Finalize(Myarray);
    Myarray:=nil;

    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    
    type
      TForm1 = class(TForm)
        Array_01_static: TButton;
        Array_01_dynamic: TButton;
        Array_02_static: TButton;
        Array_02_dynamic: TButton;
        Memo1: TMemo;
        Button1: TButton;
        procedure Array_01_staticClick(Sender: TObject);
        procedure Array_01_dynamicClick(Sender: TObject);
        procedure Array_02_staticClick(Sender: TObject);
        procedure Array_02_dynamicClick(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        myarray02_02:array of array of string;//定義動態二維數組
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.Array_01_staticClick(Sender: TObject);
    var
      myarray01_01:array[0..2] of string;
      i:Integer;
    begin
      //myarray01_01[0]:='0_A';
      //myarray01_01[1]:='1_A';
      //myarray01_01[2]:='2_A';
      for i:=Low(myarray01_01) to High(myarray01_01)  do
      begin
        myarray01_01[i]:=IntToStr(i)+'_A';
      end;
      Memo1.Clear;
      for i:=Low(myarray01_01) to High(myarray01_01)  do
      begin
        Memo1.Lines.Add('i=  '+IntToStr(i)+' Value: '+myarray01_01[i]);
      end;
    end;
    
    procedure TForm1.Array_01_dynamicClick(Sender: TObject);
    var
      myarray01_02:array of string;
      i:Integer;
    begin
      SetLength(myarray01_02,3);
      for i:=Low(myarray01_02) to High(myarray01_02)  do
      begin
        myarray01_02[i]:=IntToStr(i)+'_B';
      end;
      Memo1.Clear;
      for i:=Low(myarray01_02) to High(myarray01_02)  do
      begin
        Memo1.Lines.Add('i=  '+IntToStr(i)+' Value: '+myarray01_02[i]);
      end;
      SetLength(myarray01_02,0); //釋放數組空間
    end;
    
    procedure TForm1.Array_02_staticClick(Sender: TObject);
    var
      myarray02_01:array [0..2]of array [0..3]of string;//定義靜態二維數組
      i,j,n:Integer;
    begin
      n:=0;
      for i:=Low(myarray02_01) to High(myarray02_01) do
      begin
        for j:=Low(myarray02_01[i]) to High(myarray02_01[i]) do
        begin
          Inc(n);
          myarray02_01[i][j]:=IntToStr(n)+'_C'
        end;
      end;
    
      Memo1.Clear;
      for i:=Low(myarray02_01) to High(myarray02_01) do
      begin
        for j:=Low(myarray02_01[i]) to High(myarray02_01[i]) do//注意,這裡是針對每個第一維元素里面包含的第二維元素的循環!
        begin
          Memo1.Lines.Add('i=  '+IntToStr(i)+ ' j=  '+IntToStr(j)+' Value: '+myarray02_01[i][j]);
        end;
      end;
    
    end;
    
    procedure TForm1.Array_02_dynamicClick(Sender: TObject);
    var
      //myarray02_02:array of array of string;//定義動態二維數組
      i,j,n:Integer;
    begin
      n:=0;
      SetLength(myarray02_02,100);
    
      for i:=Low(myarray02_02) to High(myarray02_02) do
      begin
        SetLength(myarray02_02[i],100);//給每個一維元素分配5個二維空間(即每個一維元素裡面都有5個元素)
      end;
      for i:=Low(myarray02_02) to High(myarray02_02) do
      begin
        for j:=Low(myarray02_02[i]) to High(myarray02_02[i]) do//針對每個第一維元素里面包含的第二維元素的循環
        begin
          Inc(n);
          myarray02_02[i][j]:=IntToStr(n)+'_D'
        end;
      end;
    
      Memo1.Clear;
      for i:=Low(myarray02_02) to High(myarray02_02) do
      begin
        for j:=Low(myarray02_02[i]) to High(myarray02_02[i]) do
        begin
          Memo1.Lines.Add('i=  '+IntToStr(i)+ ' j=  '+IntToStr(j)+' Value: '+myarray02_02[i][j]);
        end;
      end;
      {
      for i:=Low(myarray02_02) to High(myarray02_02) do
      begin
        SetLength(myarray02_02[i],0);//先釋放二維裡的空間
      end;
    
      SetLength(myarray02_02,0);//再釋放一維的空間
      } //這裡真的有必要釋放2次嗎?把這2句代碼拿出來放到按鈕里對比測試一下看下效果~~
    end;
    
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      i:Integer;
    begin
      //這裡為了說明有無必要釋放2次,先2次釋放一起運行一遍,然後再注釋掉第1次釋放的之後
      //再運行,同時打開工作管理員,選擇‘處理程序’頁,找到當前運行的exe,對比看看
      //該exe的‘記憶體(私人工作集)’的2次運行有啥差別。
      {for i:=Low(myarray02_02) to High(myarray02_02) do
      begin
        SetLength(myarray02_02[i],0);//先釋放二維裡的空間
      end;
      }
      SetLength(myarray02_02,0);//再釋放一維的空間
      //事實證明,先釋放二維再釋放一維和直接釋放一維的效果一樣!調試時也能看到2種釋放
      //方式之後數組里的值都會被清空!
    end;
    
    end.

     form窗体代码:

    object Form1: TForm1
      Left = 417
      Top = 394
      Width = 511
      Height = 234
      Caption = 'Form1'
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'MS Sans Serif'
      Font.Style = []
      OldCreateOrder = False
      PixelsPerInch = 96
      TextHeight = 13
      object Array_01_static: TButton
        Left = 3
        Top = 38
        Width = 117
        Height = 25
        Caption = 'Array_01_static'
        TabOrder = 0
        OnClick = Array_01_staticClick
      end
      object Array_01_dynamic: TButton
        Left = 4
        Top = 96
        Width = 118
        Height = 25
        Caption = 'Array_01_dynamic'
        TabOrder = 1
        OnClick = Array_01_dynamicClick
      end
      object Array_02_static: TButton
        Left = 376
        Top = 38
        Width = 103
        Height = 25
        Caption = 'Array_02_static'
        TabOrder = 2
        OnClick = Array_02_staticClick
      end
      object Array_02_dynamic: TButton
        Left = 376
        Top = 98
        Width = 106
        Height = 25
        Caption = 'Array_02_dynamic'
        TabOrder = 3
        OnClick = Array_02_dynamicClick
      end
      object Memo1: TMemo
        Left = 132
        Top = 4
        Width = 231
        Height = 144
        ImeName = '中文(?体) - 搜狗拼音?入法'
        Lines.Strings = (
          'Memo1')
        ScrollBars = ssBoth
        TabOrder = 4
      end
      object Button1: TButton
        Left = 393
        Top = 141
        Width = 75
        Height = 25
        Caption = '釋放'
        TabOrder = 5
        OnClick = Button1Click
      end
    end
  • 相关阅读:
    MATLAB函数大全 .
    让隐藏的virtualBox菜单重新显示
    【转载】matlab 脚本文件和函数文件
    Ubuntu下用命令行快速打开各类型文件
    关于存货的成本计价方式
    C# .net asp学习笔记
    在DLL中怎么共用一个全局变量
    如果比较表中同类型多列值是否相等?
    统计报表(用ROLLUP 汇总数据)
    UML建模
  • 原文地址:https://www.cnblogs.com/168-h/p/15247625.html
Copyright © 2020-2023  润新知