Hi Mario,
if you use getDocument() to get the DOM tree that the parser built, the memory is owned by the parser, and will be deleted when the parser is deleted; if you plan to use a single parser to parse multiple sources and destroy the DOM tree immediately after that, you should call adoptDocument() and the invoke release() on the DOMDocument once you are done with it.

Alberto

Freimann, Mario wrote:
- Xerces-C++ version number: 2.8
- Platform: Windows 32Bit
- Operating system and version number: Windows Server 2003 SP 2
- Compiler and version number:  MSVC 6 SP6
- Built Xerces by myself

I'm parsing a xml document. Therefore I have a XercesDOMParser instance. I 
create this instance once and reuse it to scan one xml document cyclically. The 
xml document is valid. I get some data from the document. With every parse 
Purify reports a _potential_ memory leak of 1680 Bytes. But If I start the 
program without purify the memory consumption increases all the time. So I 
think it is a memory leak. Is this a memory leak or do I have to add some more 
release or cleanup calls (if so where?)?

The following code extract eplains the code (error checking deleted for 
simplicity). I changed my program to do only the parse function.

Creating the parser (only once):
=======================

DOMDocument* _xmlDoc = NULL;
DOMNode* _actualNode = NULL;
XercesDOMParser* _parser = NULL;

XMLPlatformUtils::Initialize();

_parser = new XercesDOMParser();

 _parser->setValidationScheme(XercesDOMParser::Val_Auto);
 _parser->setIncludeIgnorableWhitespace(false);
 _parser->setDoNamespaces(true);
 _parser->setDoSchema(false);

 _parser->setErrorHandler(this);
Parsing the file (cyclically):
====================

do
{
  if (_xmlDoc!=NULL)
  {
   _xmlDoc->release();
  }

 try
 {
  transcodexmlch = XMLString::transcode(filename);
  _parser->parse(transcodexmlch);
  XMLString::release(&transcodexmlch);
 }
 catch ()...

_xmlDoc = _parser->getDocument();

_actualNode = _xmlDoc->getDocumentElement();
} while ( true );


Purify shows a memory leak of total 2680 Bytes. The following trace gives the 
biggest memory leak:

[I] MPK: Potential memory leak of 1288 bytes from 23 blocks allocated in 
xercesc_2_8::MemoryManagerImpl::allocate(UINT) [XERCES-C_2_8D.DLL]
        Offset 0x00000008 referenced by 0x024e9370, a location in a C++ new 
block
        Offset 0x00000008 referenced by 0x024ef170, a location in a C++ new 
block
        Distribution of potentially leaked blocks
        Allocation location
            new(UINT)      [E:\DEVELOP\program\DEBUG\XERCES-C_2_8D.DLL]
            xercesc_2_8::MemoryManagerImpl::allocate(UINT) 
[E:\develop\xerces-c-src_2_8_0\src\xercesc\internal\MemoryManagerImpl.cpp:35]
                {
                    void* memptr;
                    try {
             =>         memptr = ::operator new(size);
                    }
                    catch(...) {
                        throw OutOfMemoryException();
            xercesc_2_8::XMemory::new(UINT,MemoryManager::xercesc_2_8 *) 
[E:\develop\xerces-c-src_2_8_0\src\xercesc\util\XMemory.cpp:67]

                    size_t headerSize = 
XMLPlatformUtils::alignPointerForNewBlockAllocation(
                                                        sizeof(MemoryManager*));
             =>     void* const block = manager->allocate(headerSize + size);
                    *(MemoryManager**)block = manager;

                    return (char*)block + headerSize;
            xercesc_2_8::IGXMLScanner::scanStartTagNS(bool&) 
[E:\develop\xerces-c-src_2_8_0\src\xercesc\internal\IGXMLScanner.cpp:2393]
                        if (fGrammarType == Grammar::DTDGrammarType) {
                            elemDecl = new (fMemoryManager) DTDElementDecl(
                                qnameRawBuf, uriId, DTDElementDecl::Any, 
fMemoryManager
             =>             );
                            
elemDecl->setId(fDTDElemNonDeclPool->put((DTDElementDecl*)elemDecl));
                        }
                        else if (fGrammarType == Grammar::SchemaGrammarType)  {
            xercesc_2_8::IGXMLScanner::scanContent(void) 
[E:\develop\xerces-c-src_2_8_0\src\xercesc\internal\IGXMLScanner.cpp:896]

                                    case Token_StartTag :
                                        if (fDoNamespaces)
             =>                             scanStartTagNS(gotData);
                                        else
                                            scanStartTag(gotData);
                                        break;
            xercesc_2_8::IGXMLScanner::scanDocument(InputSource::xercesc_2_8 
const&) 
[E:\develop\xerces-c-src_2_8_0\src\xercesc\internal\IGXMLScanner.cpp:214]
                        else
                        {
                            // Scan content, and tell it its not an external 
entity
             =>             if (scanContent())
                            {
                                // Do post-parse validation if required
                                if (fValidate)
            xercesc_2_8::XMLScanner::scanDocument(WORD const* const) 
[E:\develop\xerces-c-src_2_8_0\src\xercesc\internal\XMLScanner.cpp:460]
                    }

                    Janitor<InputSource> janSrc(srcToUse);
             =>     scanDocument(*srcToUse);
                }

                void XMLScanner::scanDocument(  const   char* const systemId)
            xercesc_2_8::AbstractDOMParser::parse(WORD const* const) 
[E:\develop\xerces-c-src_2_8_0\src\xercesc\parsers\AbstractDOMParser.cpp:538]
                    try
                    {
                        fParseInProgress = true;
             =>         fScanner->scanDocument(systemId);
                    }
                    catch(const OutOfMemoryException&)
                    {
            PAR_XMLDOMParser::parseFile(char *) 
[E:\develop\program\source\xmlwrapper.cxx:378]
                    try
                    {
                        transcodexmlch = XMLString::transcode(filename);
             =>         _parser->parse(transcodexmlch);
                        XMLString::release(&transcodexmlch);
                    }
                    catch(const XMLException& toCatch)

Any help is appreciated.


With kind regards,

Mario Freimann


Reply via email to