在添加节点后,如果节点的Data所指向的record结构体内有string类型的变量,关闭程序时会造成内在泄漏。各位同仁有什么好的解决办法?测试程序(工程文件引用单元最前面加上FastMM和FastMessages单元或加上CnMemProf单元即可检测出内存泄漏)unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, VTHeaderPopup, VirtualTrees, StdCtrls;type
  TMyStr = record
    s: String;
  end;
  PMyStr = ^TMyStr;  TForm1 = class(TForm)
    tree: TVirtualStringTree;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure treeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
  node: PVirtualNode;
  p: PMyStr;
begin
  node := tree.AddChild(nil);
  p := tree.GetNodeData(node);
  if p <> nil then
  begin
    p^.s := IntToStr(GetTickCount);
  end;
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  tree.Clear;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
  tree.NodeDataSize := SizeOf(TMyStr);
end;procedure TForm1.treeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
  p: PMyStr;
begin
  p := tree.GetNodeData(Node);
  if p <> nil then
  begin
    CellText := p^.s;
  end;
end;end.

解决方案 »

  1.   

    rocedure TForm1.Button1Click(Sender: TObject);
    var
      node: PVirtualNode;
      p: PMyStr;
    begin
      new(p); //加上这句话
      node := tree.AddChild(nil);
      p := tree.GetNodeData(node);
      if p <> nil then
      begin
        p^.s := IntToStr(GetTickCount);
      end;
    end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      tree.Clear;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      tree.NodeDataSize := SizeOf(TMyStr);
    end;procedure TForm1.treeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
    var
      p: PMyStr;
    begin
      new(p); //加上这句话
      p := tree.GetNodeData(Node);
      if p <> nil then
      begin
        CellText := p^.s;
      end;
    end;end.
      

  2.   

    procedure TForm1.Button1Click(Sender: TObject);
    var
      node: PVirtualNode;
      p: PMyStr;
    begin
      new(p); //加上这句话
      node := tree.AddChild(nil);
      p := tree.GetNodeData(node);
      if p <> nil then
      begin
        p^.s := IntToStr(GetTickCount);
      end;
    end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      tree.Clear;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      tree.NodeDataSize := SizeOf(TMyStr);
    end;procedure TForm1.treeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
    var
      p: PMyStr;
    begin
      new(p); //加上这句话
      p := tree.GetNodeData(Node);
      if p <> nil then
      begin
        CellText := p^.s;
      end;
    end;
      

  3.   

    to fangsp: 在哪两处加上New(p),内存泄漏会更严重的。
    ps: TVirtualStringTree是自已管理内存的。
      

  4.   

    在 OnFreeNode 事件中,取结构体,然后赋值为空字符串。
    procedure TfmMain.vstFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
    var
      p: PMyStr;
    begin
      p := tree.GetNodeData(Node);
      p.s:='';
    end;
      

  5.   

    Node的Data需要手工FREE吗? 我都没有FREE过, 也会内存泄漏吗???
      

  6.   

    不是自己分配的不需要的。即使FREE也会报错。怀疑是不是TStringTreeView的BUG来的。
      

  7.   

    d2009下.AddChild(nil)返回的指针依然为nil! 4.8.5