今天基于MSXML4.0实现SAX解析XML。但是不知道为什么下面这里不会造成内存泄漏?
var
  xmlReader: TSAXXMLReader40;
begin
  ...
  xmlReader := TSAXXMLReader40.Create(self);  //后面我没有去Free它,Free了反而出错。
  ...
end;
用内存检测工具也检测不出内存泄漏。
谁能告诉我这是为什么?

解决方案 »

  1.   

    因为Create(self);  带了self时就交给它的属主来释放,如果是Create(nil);  那就要自己释放了
      

  2.   

    上面说的属主就是只self,就是你这个过程/函数所在的类
      

  3.   

    可是还有另外一个对象也是这样子啊。  TSAXHandler = class(TAutoObject, IVBSAXEntityResolver, IVBSAXDTDHandler,
                              IVBSAXContentHandler, IVBSAXErrorHandler)这个是我写的类。
    也是Create后,不用Free,Free之后反而会出错,然后出现内存泄漏,真奇怪。
      

  4.   

    当“self”释放时,xmlReader 跟着也释放了,如果你自己再去释放,大多数运气好是不会有问题,偶尔还会出错
      

  5.   

    -_-# 这跟面向对象没关系,唉,马甲裤子少了还真被看作入门小菜鸟了。我只是不了解COM,以及MS对SAX的实现。不知道是否事件处理器的内存会被XMLReader所管理,所以才不会报内存泄漏。
    还是说使用COM的对象不是我这种用法?
      

  6.   

    楼上的哥哥,你说的这个 是哪个出版社的?我一定买一本,原来也看过相关的书籍,但是都是关于c的,不知道是否一样,再有,小弟是初涉delphi,请指点条明路
      

  7.   

    哈哈,原来碰上前辈了
    不好意思,我也是前两个月才开始研究面向对象的to: burberry(翔翔)
    那本书是刘艺的,出版社我忘了
      

  8.   

    TSAXHandler 从接口继承下来的类本身就不用释放
    我说的都是基础,不敢在前辈面前班门弄釜
    还是搬个凳子学习听讲
      

  9.   

    你看看TComponent的源码部分,当你Create(Self)时,就将这个东西register到了Self,而Self释放的死后,会将自己的一个类似HashTable中的对象一一释放,
    因此不需要你释放,你一定要释放,就
    FreeAndNil(theObject);
      

  10.   

    如果用creat(self),当它的容器消失时会自动释放的,如果用creat(nil),则需要手工释放
      

  11.   

    嗯,XMLReader的解决了。
    bee2518兄说:TSAXHandler不能释放的原因真的是“从接口继承下来的类不用释放”。我好像没听过这句话。可有出处?var
      xmlReader: TSAXXMLReader40;
      saxHandler: TSAXHandler;  //这个对象含有一个TObjectList,在Create时被创建
    begin
      saxHandler := TSAXHandler.Create;
      xmlReader := TSAXXMLReader40.Create(self);
      try
        xmlReader.contentHandler := saxHandler;
        xmlReader.errorHandler := saxHandler;
        xmlReader.parseURL(edtFile.Text);
      finally
        //若在这里释放saxHandler反而会出错
      end;
    end;程序结束后无内存泄漏,是因为每走过一遍这个程序,就会创建一个TSAXHandler。
    而这个对象很奇怪,如果我运行这个函数5遍,就会创建了TSAXHandler对象出来,直到程序推出时,才一一被释放。
    也就是说,它虽然是一个局部变量,但是内存却被某个东西管理着。我想知道管理它的是什么,是不是COM上面有什么机制,会对继承自TAutoObject的对象进行内存管理?最重要的是,如果我要即时释放这个对象,该怎么办?谁解决了,100分就是他D,谢谢各位大侠。
      

  12.   

    我不懂COM,但看你的代码,saxhandler被xmlreader使用,如果在finally中释放,可能就出错了,如果你先释放xmlreader,再释放saxhandler试试。
      

  13.   

    问题在于接口用完没减小引用计数。释放saxhandler之前要把
    xmlReader.contentHandler := nil;
    xmlReader.errorHandler := nil;
    然后才能
    saxhandler.free;
      

  14.   

    var
      xmlReader: TSAXXMLReader40;
      saxHandler: TSAXHandler;  //这个对象含有一个TObjectList,在Create时被创建
    begin
      saxHandler := TSAXHandler.Create;
      xmlReader := TSAXXMLReader40.Create(self);
      try
        xmlReader.contentHandler := saxHandler;
        xmlReader.errorHandler := saxHandler;
        xmlReader.parseURL(edtFile.Text);
      finally
        //若在这里释放saxHandler反而会出错
      end;
    end;唉,马甲裤子少了还真被看作入门小菜鸟了。这样的代码写出了,看来你也只能被看作菜鸟了……汗
      

  15.   

    同意“ TSAXHandler 从接口继承下来的类本身就不用释放”把接口置为nil就可以了具体原因,可以去看看《Inside vcl》
    忘记了具体在哪一章,在阐述TInterfacedObject的时候说过
    大意是这样的:
    “在接口被置为空的时候,编译器自动加入了释放对象的机器码”TAutoObject继承自TComObject,
    TComObject和TInterfacedObject的实现过程是差不多的
    同样的释放原理也适用
      

  16.   

    请看“Delphi com组件编程”,里面有详细的介绍Delphi对接口的实现。
      

  17.   

    http://www.somade.com/是个很专业的技术社区,去那里找找吧,或许有你要的答案~
      

  18.   

    这个涉及到内存托管的问提,SELF说明把这个实例交给SELF来托管,负责其销毁