在treeview当中我使用了指针 
 while not eof do 
       begin 
         new(myPro); 
         myPro.Code :=fieldbyname('AccusalCode').Value; 
         myPro.name:=fieldbyname('AccusalName').Value+' '+Fieldbyname  ('Con 
tent').Value ; 
         myPro.level :=fieldbyname('AccusalLevel').Value ; 
         myPro.Pcode  :=fieldbyname('SuperiorCode').Value ; 
         myNode:=TreeView1.Items.AddChildObject(node,fieldbyname('AccusalNam 
e').Value+' '+Fieldbyname('Content').Value ,myPro ); 
         treeload(mynode,fieldbyname('AccusalCode').Value ); 
           dispose(PTreeNodePro(myPro)); 
         next; 
end; 
然后我再点击树控件中 
 new(myPro); 
    myPro:=PTreeNodePro(Treeview1.Selected.Data) ;     mycode:=myPro.code; 
使用这个访问,报内存访问错误 
如果在加载树时不释放mypro,就不会出现错误 
但是会占用大量的内存,我如何释放掉,请指教

解决方案 »

  1.   

    myNode:=TreeView1.Items.AddChildObject(node,fieldbyname('AccusalNam 
    e').Value+' '+Fieldbyname('Content').Value ,myPro ); 
             treeload(mynode,fieldbyname('AccusalCode').Value ); 
               dispose(PTreeNodePro(myPro));
    你在加载树时释放了mypro,等于又把树节点的指针所指数据释放掉了,这样,树的每个节点的指针指向的都是nil,你又怎么能够访问到数据呢.
     new(myPro); 这句根本没必要,建议楼主先搞清指针到底是怎么回事,再来写这种程序吧。
      

  2.   

    procedure TfrmEntityLaw.treeload(node:TTreeNode;myCode:string;lawcode:string);
    var
     myNode:TTreeNode;
     MyQuery:TADOQuery;
     myPro:PTreeNodePro1;
     mystr:string;
    begin
      //
      mystr:=lawcode;
      myQuery:=TADOQuery.Create(nil);
      myQuery.Connection :=DM.ADOConnection1 ;
      with myQuery do
      begin
        close;
        with sql do
        begin
          clear;
          add('select * from EntityLaw where LawCode='+''''+mystr+''''+' and SuperiorItemCode='+''''+mycode+''''+' order by ItemCode');
        end;
        //parameters.ParamValues[:Scode] :=myCode;
        prepared;
        try
          open;
        except
          raise;
        end;    if recordcount=0 then
          exit;
        if recordcount>0 then
        begin
          first;
          while not eof do
          begin
            new(myPro);
            myPro.Code :=fieldbyname('ItemCode').Value;
            myPro.name:=fieldbyname('SectionName').Value ;
            myPro.Level:=fieldbyname('SectionLevel').Value ;
            myPro.Pcode  :=fieldbyname('SuperiorItemCode').Value ;
            myPro.lawcode :=mystr;
            myNode:=TreeView1.Items.AddChildObject(node,fieldbyname('SectionName').Value ,myPro );
            treeload(mynode,fieldbyname('ItemCode').Value,mystr );
            next;
          end;
        end;
      end;
    end;procedure TfrmEntityLaw.FormShow(Sender: TObject);
    begin
     sysInit;
     Treeview1.Items.Clear ;
     BitBtn3.Click ;
    end;
    procedure TfrmEntityLaw.BitBtn3Click(Sender: TObject);
    var
     myPro:PTreeNodePro1;
     myNode:TTreeNode;
    begin
      TreeView1.Items.Clear ;
      with DM.ADOQuery1 do
      begin
        close;
        with sql do
        begin
          clear;
          add('select * from LawList where Flag=1');
        end;
        prepared;
        try
          open;
        except
          raise;
        end;    first;
        while not eof do
        begin
            new(myPro);
            myPro.Code :=fieldbyname('LawCode').Value;
            myPro.name:=fieldbyname('LawName').Value;
            myPro.Pcode  :=fieldbyname('SuperiorLawCode').Value ;
            myPro.lawcode :='';
            myNode:=TreeView1.Items.AddChildObject(nil,fieldbyname('LawName').Value,myPro );
            treeLoad(myNode,fieldbyname('LawCode').Value ,myPro.code);
            next;
        end;
        close;
      end;
    end;
    procedure TfrmEntityLaw.Button1Click(Sender: TObject);
    var
    I:integer;
    myPro:PTreeNodePro1;
    begini:=TreeView1.Items.Count;
    while (i<>0) do
    begin
          myPro:=TreeView1.Items.Item[i-1].Data;
          if Assigned(myPro) then
          begin
           Dispose(myPro);
           TreeView1.Items.Item[i-1].Data:=nil;
           TreeView1.Items.Delete(TreeView1.Items.Item[i-1]);
         end;
           i:=TreeView1.Items.Count;
    end;
    end;我希望当点击button1的时候,内存立即释放,可是,只有当整个程序关闭的时候才能释放  
      

  3.   

    在TreeView的deletion事件中写
    TreeView1Deletion(Sender: TObject; Node: TTreeNode);
    begin
      if node.data<>nil then dispose(node.data);
    end;
    这样在每删除一个节点时,就会删除该节点附加的信息。具体的代码可以根据实际编写,上面的代码仅仅只是一个实例。
      

  4.   

    {type 
    rCustNodeInfo=Record {记录客户信息}
             sFlag           :string;{1:cust,2:Acct}
             sid             :string;
             scustname       :string;
             scust_nbr_97    :string;
             scust_state     :string;
    end;
    prCustNodeInfo:^rCustNodeInfo;}GetMem(prCustNodeInfo,sizeof(rCustNodeInfo));  
    zeromemory(prCustNodeInfo,sizeof(rCustNodeInfo));
    //rCustNodeInfo为自定义结构,prCustNodeInfo为其指针  prCustNodeInfo^.sFlag := '-1';
      prCustNodeInfo^.sid := '';
      prCustNodeInfo^.scustname := '';
      prCustNodeInfo^.scust_nbr_97 := '';
      prCustNodeInfo^.scust_state := '';
      RootNode := TreeView_Cust.Items.AddChildObject(
                                               nil,'test',prCustNodeInfo);  //prCustNodeInfo不能现在释放,在窗口关闭时,将所有挂在treeview上的内存释放就行了
     //如下:
    procedure FreeTree;
    var
      i:integer;
    begin
      for i:=0 to TreeView_Cust.Items.Count-1 do
      begin
        if TreeView_Cust.Items[i].Data <> nil then
        begin
          FreeMem(TreeView_Cust.Items[i].Data,sizeof(rCustNodeInfo));
        end;
      end;
    end;
      

  5.   

    别dispose 即可,因为你加入data的是指针,而引用的是该内存区域;你dispose 了,当然没了~~只有在关闭应用程序的时候遍历释放掉!delphi的treeView 不会主动释放的。
      

  6.   

    去掉第一句
    //new(myPro); 
        myPro:=PTreeNodePro(Treeview1.Selected.Data) ;     mycode:=myPro.code; 
      

  7.   

    在TTreeView的Deletion事件中写
      Dispose(Node.Data);
    就行了