一个treeview中,为便于对各个节点的管理,在节点的时候,给node的data上放了一个指针。代码如下:
PNode=^TNode;
  TNode=record
    id:integer;
    test:array[1..100000] of integer;
  end;
....
procedure TFormMain.Button1Click(Sender: TObject);
var
  pn1:pnode;
  cnode:TTreeNode;
begin   TreeView.Items.Clear;
   new(pn1);
   cnode:=TreeView.Items.AddChildObject(nil,'test',pn1);
   ....
   while not eof do
    begin
      new(pn1);
      pn1.id:=FieldByName('id').AsInteger;
      for i:=0 to TreeView.Items.Count-1 do
      begin
        if pnode(TreeView.Items.Item[i].Data).id=FieldByName('pid').AsInteger then
        begin
          cnode:=TreeView.Items.AddChildObject(TreeView.Items.Item[i],FieldByName('name').AsString,pn1);
         end;
      end;
      next;
    end;上面是往treeview中添加一个数据库表的内容我想用下面的事件来释放所占的内存
procedure TFormMain.TreeView1Deletion(Sender: TObject;
  Node: TTreeNode);
var
  pn1:pnode;
begin
     pn1:=node.data;
     dispose(pn1);     
end;我在2000在通过任务管理器观察,不停的点Button1,程序所占的内存就不断地增加,说明各个pn1所占的内存并没有释放!!!点十几次以后就提示Out of memory了!
我想问,这个情况要怎样才能使内存得到彻底的释放?

解决方案 »

  1.   

    procedure TFormMain.TreeView1Deletion(Sender: TObject;
      Node: TTreeNode);
    var
      pn1:pnode;
    begin
       if node <> nil then
       begin 
         pn1:=node.data;
         Freemem(pn1)
         //dispose(pn1);     
       end;
    end;
      

  2.   

    有2个问题:
    1:while循环中首先分配了内存,如果满足if那么该内存块被显式的使用,否则内存泄漏了
    2:我记得TreeView1Deletion好像是在节点被删除之后被调用的,如果是这样的话,会造成程序非法。
      

  3.   

    这样写:
    procedure TFormMain.TreeView1Deletion(Sender: TObject;
      Node: TTreeNode);
    var
      pn1:pnode;
    begin
         pn1:=node.data;
         pn1.Free;
    end;
      

  4.   

    没看到TNode=record
    可以
    TNode=class
        id:integer;
        test:array[1..100000] of integer;
      end;
    或者同Hedonism(努力=幸福)
    Freemem(pn1^)
      

  5.   

    还有一个问题:
    你的new 是写在if pnode(TreeView...之前的,也就是说如果if条件不满足你也new 了一个,此时数据没有加到节点上,自然也不会释放
          new(pn1);
          pn1.id:=FieldByName('id').AsInteger;
          for i:=0 to TreeView.Items.Count-1 do
          begin
            if pnode(TreeView.Items.Item[i].Data).id=FieldByName('pid').AsInteger then
            begin
              cnode:=TreeView.Items.AddChildObject(TreeView.Items.Item[i],FieldByName('name').AsString,pn1);
             end;
          end;
      

  6.   

    procedure TFormMain.Button1Click(Sender: TObject);
    var
      pn1:pnode;
      cnode:TTreeNode;
    begin   TreeView.Items.Clear;
       new(pn1);
       cnode:=TreeView.Items.AddChildObject(nil,'test',pn1);
       ....
       while not eof do
        begin
          for i:=0 to TreeView.Items.Count-1 do
          begin
            if pnode(TreeView.Items.Item[i].Data).id=FieldByName('pid').AsInteger then
            begin
              new(pn1);   //对你的程序作部分的改动
              pn1.id:=FieldByName('id').AsInteger;  //对你的程序作部分的改动      
              cnode:=TreeView.Items.AddChildObject(TreeView.Items.Item[i],FieldByName ('name').AsString,pn1);
             end;
          end;
          next;
        end;
      

  7.   

    并且你还有for语句,也就是多个node指向同一个数据,那样释放的时候也会有问题csdn真烦,居然不让连续贴3个以上的帖子
      

  8.   

    顺便问一下,出来的treeview是你要的样子吗?例如,如果查询的结果是
    id            name
    1             name11
    1             name12
    1             name13出来的结果可能会是这个样子
    name11
      |__name12
      |    |__name13
      |__name13