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