标题
    
    
        [DGL/stl/delphi] DGL 的严重 bug 还是 delphi 的严重 bug ? 
    
 
    
 	 
       
    
    clq
    
    
    
		
        浏览(0) + 
        2009-12-04 11:45:19 发表
        
编辑 
         
        
        
        
        关键字: 
        
 
        
 
        
        
        
                
        [DGL/stl/delphi] DGL 的严重 bug 还是 delphi 的严重 bug ? DGL  中这样的代码,对 tstringlist 是没有正确释放和,不能手工 free 也没有自动 free . 有严重的内存泄漏。 map:DHashMap; list:tstringlist; map.AddPair([path, list]);  换用一个 Pointer 类型中间变量才行。怪异的是只能用 Pointer 作指针,如果定义一个 tstringlist 的指针,如 type   PStringList = ^TStringList;  是不行的!!! 而且我在 delphi 7 中调试时发现两次 TStringList.Create 产生的指针值所居然是一样的!!但取出的值又不一样!不知 delphi 内部是如何实现的。感觉 Pointer 才是 delphi 的指针,而原来意义上的指针是对类的操作完全无效,要用到类的指针时必须用 Pointer  ???
         
        
        
        		
		        
                
                
     
    
 
	
	
     
    
       
    
    clq
    
    
    
    
    
    		    
    
          
              
    	unit uxml_decode; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   uDGL,   Dialogs, xmldom, XMLIntf, msxmldom, XMLDoc, StdCtrls; type   PStringList = ^TStringList;   type     TXml_decode = class(TObject)   private     XMLDocument1: TXMLDocument;     m1:DHashMap;     StringList_arr:tlist;//生成的 TStringList   public     procedure DecodeXml_sub(map: DHashMap; path: string; node: IXMLNode);     procedure putOne(path: String; map: DHashMap; node: IXMLNode);     procedure DecodeXml(const data:string);     function getOneList(path:string):tstringlist;     function getOneString(path: string): string;     constructor Create;     destructor Destroy;override;//virtual;   end; implementation //代替 map.put((node_name).toLowerCase(), node.getTextContent());//取得一个值放入 hashmap 中 procedure TXml_decode.putOne(path:String ; map:DHashMap; node : IXMLNode); var   list:tstringlist;   value:string;   obj:TObject;   iter:DIterator;   pl:PStringList;   p:Pointer; begin     //paths += path + "\r\n";     path := LowerCase(path);     list := nil;     value := node.NodeValue;//取得节点的值     //取得以前保存的值列表,如果有的话     //GetObject(map.Find([path]));     iter := map.Find([path]);     //if iter.iAtEnd(iter) then     //obj := GetObject(map.Find([path]));     //if (obj = nil) then     if diMarkFinish in iter.flags then     begin//没找到       list := tstringlist.Create;       //list := tstringlist.Create;       pl := @list;       p := list;       StringList_arr.Add(list);//用于释放       //StringList_arr.Add(pl);       //showmessage(TStringList(StringList_arr.Items[0]).text);//用于释放     end     else     begin       //obj := GetObject(iter);       //list := tstringlist(obj);       //pl := GetPointer(iter);       //list := pl^;       p := GetPointer(iter);       list := p;     end;     //在列表中加入当前项目     list.add(value);     //map.put(path, list); //    map.AddPair([path, list]); //    map.AddPair([path, pl]);     map.AddPair([path, p]); end; procedure TXml_decode.DecodeXml_sub(map:DHashMap; path:string; node:IXMLNode); var   i:integer;   childnode : IXMLNode; begin   //   for i:=0 to node.ChildNodes.Count-1 do   begin     childnode := node.ChildNodes.Nodes[i];     //showmessage(childnode.NodeName);     if childnode.IsTextElement then     begin       //showmessage(path + '/' + childnode.NodeName + ':' + childnode.NodeValue);       putOne(path + '/' + childnode.NodeName, map, childnode);     end;     DecodeXml_sub(map, path + '/' + childnode.NodeName, childnode);   end;       end; function TXml_decode.getOneList(path:string):tstringlist; //不能用这个 procedure TXml_decode.getOneList(path:string; out1:tstringlist); var   r:tstringlist; begin   //r := tstringlist(GetObject(m1.Find(['BODY/Msisdn'])));   //out1 := tstringlist(GetObject(m1.Find(['body/msisdn'])));   //out1 := tstringlist(GetObject(m1.Find([path])));   r := tstringlist(GetPointer(m1.Find([path])));   //r := tstringlist(GetObject(m1.Find(['body/msisdn'])));   //showmessage(r.Text);   result := r; end; function TXml_decode.getOneString(path:string):string; //不能用这个 procedure TXml_decode.getOneList(path:string; out1:tstringlist); var   r:tstringlist; begin   //r := tstringlist(GetObject(m1.Find(['BODY/Msisdn'])));   //r := tstringlist(GetObject(m1.Find(['body/msisdn'])));   //r := tstringlist(GetObject(m1.Find([path])));   r := tstringlist(GetPointer(m1.Find([path])));   //r := tstringlist(GetObject(m1.Find(['body/msisdn'])));   //showmessage(r.Text);   if r.Count>0   then result := r.Strings[0]   else result := ''; end; procedure TXml_decode.DecodeXml(const data: string); var   r,sl:tstringlist;   node : IXMLNode;   //m1:DHashMap; begin   //m1:=DHashMap.Create;   //XMLDocument1 := TXMLDocument.Create(application);   XMLDocument1.XML.Text := data;   XMLDocument1.Active := true;   node := XMLDocument1.DocumentElement;   DecodeXml_sub(m1, node.NodeName, node);//有内存泄漏         {   //r := tstringlist(GetObject(m1.Find(['BODY/Msisdn'])));   r := tstringlist(GetObject(m1.Find(['body/msisdn'])));   showmessage(node.NodeName);   showmessage(r.Text);   node := node.ChildNodes.Nodes[0];   //} end; destructor TXml_decode.Destroy; var   i:integer;   sl:TStringList;   pl:PStringList; begin   for i:=0 to self.StringList_arr.Count-1 do   begin     //不用,DGL会自动释放容器类的东西     sl := TStringList(StringList_arr.Items[i]);     //pl := StringList_arr.Items[i];     //sl := pl^; //    showmessage(sl.Text);     sl.Free;   end;   StringList_arr.Clear;   StringList_arr.Free;   m1.Clear;   m1.Free;   XMLDocument1.Free; end; constructor TXml_decode.Create; begin   StringList_arr := tlist.Create;      m1:=DHashMap.Create;   XMLDocument1 := TXMLDocument.Create(application); end; end.
     
    
     
 
	 
    
       
    
    clq
    
    
    
    
    
    
    
          
              
    	注意 destructor Destroy;override;//virtual; 不能少,否则不调用 free.
     
    
     
 
	 
	
    NEWBT官方QQ群1: 276678893 
    可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧. 
    但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件. 
    验证问题说明申请入群原因即可.