eurekalog捕捉到内存泄露
在窗体创建的时候创建的list 释放判断不严密造成的type
  pGamelist= ^TGamelist;//这里定义了指针
  TGamelist =packed record
  sky:Integer;
  X: Single;
  Y: Single;
  Z: Single;
  get:Boolean;
  ss:string;
 end;
这里是结构体定义
implementation{$R *.dfm}
 uses Generics.Collections;
 var
 List: TList<TGamelist>;//这里是定义的泛型数组
procedure TForm1.FormCreate(Sender: TObject);//创建list
begin
   List := TList<TGamelist>.Create;
end;
这个是创建
释放的时候出现问题了
因为没法准确判断 所以导致了两个问题
该释放的没办法释放
不该释放的释放之后出错
  
if list.count<>0 then
   begin
     list.free;
   end;
这样会导致list无法被释放,比如之前被list.clear;list.free;直接这样会导致无效的指针
奇怪的是
我在 FormCreate的时候 如果只是TList<TGamelist>.Create 不使用它就无法free
如果使用了 并且中间代码用了list.clear;因为list.count=0 按照if list.count<>0 then
   begin
     list.free;
   end;
这样又无法释放 所以导致内存泄露。Assigned 这个函数 貌似也无法判断
搞了好多天   一点眉目都没.
Delphi泛型内存泄露指针安全

解决方案 »

  1.   

    试试这样释放呢?
    if Assigned(List) then
      FreeAndNil(List);
      

  2.   

    Assigned 这个函数 貌似也无法判断
    测试过了 不知道有没其他的办法
      

  3.   

    关键是这个 FreeAndNil
    Free后把变量设为nil后Assigned才有作用
      

  4.   

    没看懂你的问题说明,你贴一段完整的不能free的代码例子来瞅瞅
      

  5.   

    我们也使用了泛型,结果内存泄露了。我使用Dispose(p)总报错!
    用“lst.Clear;”也没用!FreeAndNil()也只是释放了容器对象lst,而容器lst中记录虽然可以用lst.Clear清空,但分配的内存却没有释放,进而导致内存泄露。
      

  6.   

    我们也使用了泛型,结果内存泄露了。我使用Dispose(p)总报错!
    用“lst.Clear;”也没用!FreeAndNil()也只是释放了容器对象lst,而容器lst中记录虽然可以用lst.Clear清空,但分配的内存却没有释放,进而导致内存泄露。 这个问题后来你们怎么解决的?是不是编译器的BUG啊。这么委琐。
      

  7.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, RzLstBox;type
      TForm1 = class(TForm)
        btn1: TButton;
        mmo1: TMemo;
        lst2: TRzListBox;
        btn2: TButton;
        btn3: TButton;
        mmo2: TMemo;
        lbl1: TLabel;
        txt1: TStaticText;
        lbl2: TLabel;
        btn4: TButton;
        edt1: TEdit;    procedure FormDestroy(Sender: TObject);
        procedure FormCreate(Sender: TObject);    procedure btn4Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;type
      pGamelist= ^TGamelist;//这里定义了指针
      TGamelist =packed record
      sky:Integer;
      X: Single;
      Y: Single;
      Z: Single;
      get:Boolean;
      ss:string;
     end;var
      Form1: TForm1;
      cslist:TStringlist;
      mslist:TStringlist;
    implementation{$R *.dfm}
     uses Generics.Collections;
     var
     List: TList<TGamelist>;//这里是定义的泛型数组procedure TForm1.FormCreate(Sender: TObject);
    begin
       list:=nil;
       cslist:=nil;
       mslist:=nil;
       List := TList<TGamelist>.Create;
       cslist:=tstringlist.Create;
       mslist:=tstringlist.Create;
    end;procedure TForm1.btn4Click(Sender: TObject);
    var
    js:Integer;begin
      //list.clear;
      js:=list.count;
      FreeAndNil(list);
      if Assigned(list)=false then
       begin
        edt1.text:=inttostr(1);
        //list.free;
       end;end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
    //List.Free;
    cslist.Free;
    mslist.free;
     // FreeAndNil(List);end;end.
    按下btn4         edt1.text返回1
      

  8.   


    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;type
      pGamelist = ^TGamelist; //这里定义了指针
      TGamelist = packed record
        sky: Integer;
        X: Single;
        Y: Single;
        Z: Single;
        get: Boolean;
        ss: string;
      end;
    var
      Form1: TForm1;implementation{$R *.dfm}uses Generics.Collections;
    var
      List: TList < pGamelist > ; //这里是定义的泛型数组procedure TForm1.Button1Click(Sender: TObject);
    var
      I: Integer;
    begin
      // 手动销毁 list
      if Assigned(List) then
      begin
        edt1.Text:= IntToStr(List.Items[0]^.sky + List.Items[1]^.sky); // '3000'
      
        for I := List.Count - 1 downto 0 do
        begin
          FreeMemory(list.Items[i]);
        end;
        FreeAndNil(list);
      end
      else
        edt1.Text:= '啥也不会有, List已经挂了';
    end;procedure TForm1.FormCreate(Sender: TObject);
    var
      gl, gl2: pGamelist;
    begin
      List := TList < pGamelist > .Create;
      gl := GetMemory(SizeOf(TGamelist));
      gl2 := GetMemory(SizeOf(TGamelist));
      gl^.sky := 1000;
      gl2^.sky := 2000;
      List.Add(gl);     // 添加两项
      List.Add(gl2);
    end;procedure TForm1.FormDestroy(Sender: TObject);
    var
      I: Integer;
    begin
      // TForm1销毁时 销毁list
      if Assigned(List) then
      begin
        for I := List.Count - 1 downto 0 do
        begin
          FreeMemory(list.Items[i]);
        end;
        FreeAndNil(list);
      end;end;end.
      

  9.   

    有个逻辑错误,改一下procedure TForm1.FormDestroy(Sender: TObject);
    var
      I: Integer;
    begin
      // TForm1销毁时 销毁list
      if Assigned(List) then
      begin
        for I := List.Count - 1 downto 0 do
        begin
          FreeMemory(list.Items[i]);
          // FreeAndNil(list); 放到下面
        end;
      end;
       FreeAndNil(list); 
    end;这样,即便仅仅create,最后销毁也不会有漏网的
    [code=delphi]
    procedure TForm1.FormCreate(Sender: TObject);
    var
      gl, gl2: pGamelist;
    begin
      List := TList < pGamelist > .Create;
      //gl := GetMemory(SizeOf(TGamelist));
      //gl2 := GetMemory(SizeOf(TGamelist));
      //gl^.sky := 1000;
      //gl2^.sky := 2000;
      //List.Add(gl);     // 添加两项
      //List.Add(gl2);
    end;
    [/code]
      

  10.   

    楼上正确。
    FreeMemory(list.Items[i]);
      

  11.   

    郁闷编译无法通过。
    FreeMemory(list.Items[i]);  这句
      

  12.   

    E2010 Incompatible types: 'Pointer' and 'TGamelist'
      

  13.   

    list里的是pGamelist而不是TGamelist,TGamelist是个结构体类型,pGamelist是个指针类型,当然提示不兼容的类型。仔细看我的代码是怎么添加item的var
      gl, gl2: pGamelist; // 结构指针
    begin
      List := TList < pGamelist > .Create; // item为结构指针
      gl := GetMemory(SizeOf(TGamelist));//分配内存
      gl2 := GetMemory(SizeOf(TGamelist));
      gl^.sky := 1000; // 赋值,测试用
      gl2^.sky := 2000;
      List.Add(gl);     // 添加两个结构指针
      List.Add(gl2);