So I actually did the right thing, but I still get that damn memory leak...
I really don't understand where this could come from.
Since you have the code, if I could abuse, do you have any clue? I mean, the
code of the ParserXML object is pretty small, so I don't understand how can
this lead to a memory leak.
I use the parser this way :
ServiceMEP* ServicePRC::getServiceMiseEnPaiement(const char* p_pcFluxPRC)
{
ParserXML* l_poParser = NULL;
ServiceMEP* l_poService = NULL;
ElementXML* l_poElementXML = NULL;
try
{
//--- Convertit le flux en UTF-8
DeleteIfObject(m_pcBuffer);
m_pcBuffer= new char[(strlen(p_pcFluxPRC)*2) + 1];
memset(m_pcBuffer, '\0', (strlen(p_pcFluxPRC)*2) + 1);
XMLFactory::convertToUTF8(p_pcFluxPRC, m_pcBuffer);
//--- Parse le flux de données et récupération de l'ElementXML
correspondant
l_poParser = m_poXMLFactory->createParser();
ThrowIfNullWithMsg(l_poParser, "Impossible de récupérer une instance
de ParserXML dans getServiceMiseEnPaiement");
// parsing du flux proprement dit
l_poElementXML = l_poParser->parse(m_pcBuffer);
if (l_poElementXML != NULL)
//--- Recuperation du document racine
l_poService = new ServiceMEP(l_poElementXML);
#ifdef DEBUG
l_poService->PrintOn(cout);
#endif
//--- Nettoie les elements
m_poXMLFactory->releaseParser(l_poParser);
DeleteIfObject(m_pcBuffer);
//--- Creation des objets entites
return l_poService;
}
and of course, I delete the ServiceMEP* after using it. The ElementXML is
released by the parser since the Parser allocates the memory for the
Element.
Man I wish this was over : (
Thanks again.
Alberto Massari wrote:
>
> In order to release the DOM trees owned by the parser, you either delete
> the parser or call resetDocumentPool(). The reset() method is simply
> initializing the internal variables before a parsing operation starts.
>
> /** Reset the parser
> *
> * This method resets the state of the DOM driver and makes
> * it ready for a fresh parse run.
> */
> void reset();
>
>
> /** Reset the documents vector pool and release all the associated
> memory
> * back to the system.
> *
> * When parsing a document using a DOM parser, all memory allocated
> * for a DOM tree is associated to the DOM document.
> *
> * If you do multiple parse using the same DOM parser instance, then
> * multiple DOM documents will be generated and saved in a vector
> pool.
> * All these documents (and thus all the allocated memory)
> * won't be deleted until the parser instance is destroyed.
> *
> * If you don't need these DOM documents anymore and don't want to
> * destroy the DOM parser instance at this moment, then you can
> call this method
> * to reset the document vector pool and release all the allocated
> memory
> * back to the system.
> *
> * It is an error to call this method if you are in the middle of a
> * parse (e.g. in the mid of a progressive parse).
> *
> * @exception IOException An exception from the parser if this
> function
> * is called when a parse is in progress.
> *
> */
> void resetDocumentPool();
>
> Alberto
>
> radada ha scritto:
>> God this library is hard to use : (
>> So : the core dump is gone, thanks : ) (I removed the call to release and
>> the deletion of the DOMDocument)
>> But (there's always a but...), I get a memory leak now. This is why is
>> used
>> the reset() method on the parser at first I think.
>> The only way to release a parser and its associated objects is to delete
>> it
>> or is there another method to call?
>> Thanks, again : /
>>
>>
>> Alberto Massari wrote:
>>
>>> If you use XercesDOMParser::getDocument to retrieve the parsed
>>> DOMDocument, you should NOT call either DOMDocument::release or delete
>>> the object, as the DOM tree is owned by the parsed and will be deleted
>>> by him when you release it.
>>> If you are going to keep the parser for a long time, you may want to
>>> handle the lifetime of the DOM tree yourself; but in that case you
>>> should retrieve it from the parser by using
>>> XercesDOMParser::adoptDocument, and you will have to use
>>> DOMDocument::release to free it (don't use "delete" as it will not
>>> perform all the cleanup, and in any case you are not assured it has been
>>> created by the same "new" operator matching your "delete" operator).
>>>
>>> Alberto
>>>
>>> P.S. it is written in the documentation as well:
>>>
>>> /** Get the DOM document
>>> *
>>> * This method returns the DOMDocument object representing the
>>> * root of the document tree. This object provides the primary
>>> * access to the document's data.
>>> *
>>> * The returned DOMDocument object is owned by the parser.
>>> *
>>> * @return The DOMDocument object which represents the entire
>>> * XML document.
>>> */
>>> DOMDocument* getDocument();
>>>
>>> /** Adopt the DOM document
>>> *
>>> * This method returns the DOMDocument object representing the
>>> * root of the document tree.
>>> *
>>> * The caller will adopt the DOMDocument and thus is responsible to
>>> * call DOMDocument::release() to release the associated memory.
>>> * The parser will not delete it. The ownership is transferred
>>> * from the parser to the caller.
>>> *
>>> * @return The adopted DOMDocument object which represents the
>>> entire
>>> * XML document.
>>> */
>>> DOMDocument* adoptDocument();
>>>
>>>
>>>
>>> radada ha scritto:
>>>
>>>> Thanks Alberto, but I'm perplex now : should I call the release method
>>>> on
>>>> the
>>>> DOMDocument ou should I just delete it w/o calling release?
>>>> Thx man : )
>>>>
>>>>
>>>> Alberto Massari wrote:
>>>>
>>>>
>>>>> You shouldn't explicitly release a DOMDocument unless you adopted it
>>>>> from the DOMParser, or it will try to release it after it has already
>>>>> been deleted.
>>>>> You shouldn't also attempt to delete an object that you already
>>>>> released.
>>>>>
>>>>> Alberto
>>>>>
>>>>> radada ha scritto:
>>>>>
>>>>>
>>>>>> Hi there : )
>>>>>>
>>>>>> I think I'm going nuts : (
>>>>>> Thanks to Alberto, I've got a code which is approximatively good. As
>>>>>> told
>>>>>> in
>>>>>> a previous post, I implemented a functional layer over the xerces
>>>>>> library
>>>>>> so
>>>>>> that we can use it in our software at work.
>>>>>> In order to control as much as possible the memory leaks, I created a
>>>>>> singleton which can (and only it can) create DOMDocument and
>>>>>> XercesDOMParser. It is reponsible too for the releasing of the
>>>>>> objets.
>>>>>>
>>>>>> So for the parser, I've got a release method :
>>>>>>
>>>>>> void XMLFactory::releaseParser(ParserXML* p_poParser)
>>>>>> {
>>>>>> #ifdef AFF
>>>>>> cout << "XMLFactory::releaseParser()" << endl;
>>>>>> #endif
>>>>>>
>>>>>>
>>>>>> // suppression en se basant sur les adresses des objets
>>>>>> for (int i=0; i<m_oListeParserXML.entries(); i++)
>>>>>> {
>>>>>> ParserXML* ptr = NULL;
>>>>>> ptr = m_oListeParserXML.at(i);
>>>>>> if (ptr == p_poParser)
>>>>>> m_oListeParserXML.removeAt(i);
>>>>>> }
>>>>>>
>>>>>> // on delete l'objet (on test avant s'il n'est pas NULL avec le
>>>>>> ThrowIfNullWithMsg)
>>>>>> DeleteIfObject(p_poParser);
>>>>>> }
>>>>>>
>>>>>> In the destructor of the Parser, I've got this :
>>>>>>
>>>>>> ParserXML::~ParserXML()
>>>>>> {
>>>>>> #ifdef AFF
>>>>>> cout << "Destructeur de ParserXML" << endl;
>>>>>> #endif
>>>>>>
>>>>>> if (m_poDocument != NULL)
>>>>>> {
>>>>>> m_poDocument->release();
>>>>>> }
>>>>>> m_poDOMParser->reset();
>>>>>>
>>>>>> DeleteIfObject(m_poDOMParser);
>>>>>> DeleteIfObject(m_poErrorHandler);
>>>>>> DeleteIfObject(m_poDOMDocument);
>>>>>> DeleteIfObject(m_poElementXML);
>>>>>> }
>>>>>>
>>>>>> Some strange things happen, especially when I compare my code to the
>>>>>> DOM
>>>>>> Programming Guide Chapter "Constructing a XercesDOMParser"
>>>>>> (http://xerces.apache.org/xerces-c/program-dom-3.html). It seems
>>>>>> that,
>>>>>> to
>>>>>> delete a parser and its ressources, one only have to delete the
>>>>>> parser.
>>>>>> If I do that, I get a core Dump while deleting the DOMDocument.
>>>>>> So I added a m_poDOMParser->resetDocumentPool(), but it had the same
>>>>>> effect.
>>>>>> Then I tried with m_poDOMParser->reset() and it did work! Well, not
>>>>>> that
>>>>>> much. Sometimes it does, sometimes it doesn't. I still get a core
>>>>>> Dump
>>>>>> sometimes, always when deleting the parser...
>>>>>>
>>>>>> Just for the record, here is the parsing method :
>>>>>>
>>>>>> ElementXML* ParserXML::parse(const char* p_pcBuffer)
>>>>>> {
>>>>>> #ifdef AFF
>>>>>> cout << "ParserXML::parse()" << endl;
>>>>>> #endif
>>>>>>
>>>>>> // Si aucun buffer n'est passé, on renvoie NULL
>>>>>> if (p_pcBuffer == NULL)
>>>>>> {
>>>>>> return NULL;
>>>>>> }
>>>>>>
>>>>>> // si le parser n'a pas libéré les ressources du précédent parse
>>>>>> if (m_bDocumentParsed)
>>>>>> {
>>>>>> if (m_poDocument != NULL)
>>>>>> {
>>>>>> m_poDocument->release();
>>>>>> }
>>>>>> m_poDOMParser->reset();
>>>>>> m_bDocumentParsed = false;
>>>>>> }
>>>>>>
>>>>>> char* l_pcMessage;
>>>>>> // on crée un objet pour le parsing
>>>>>> MemBufInputSource l_oInputSource((const XMLByte*)p_pcBuffer,
>>>>>> strlen(p_pcBuffer),
>>>>>> (const XMLCh*) "ParserXML");
>>>>>> try
>>>>>> {
>>>>>> // on parse
>>>>>> m_poDOMParser->parse(l_oInputSource);
>>>>>>
>>>>>> // on récupère le DOMDocument parsé
>>>>>> m_poDocument = m_poDOMParser->getDocument();
>>>>>>
>>>>>> // on libère la mémoire si besoin
>>>>>> DeleteIfObject(m_poElementXML);
>>>>>> //on crée un nouveau ElementXML avec les données du DOMDocument
>>>>>> m_poElementXML = new
>>>>>> ElementXML(m_poDocument->getDocumentElement());
>>>>>> // on indique que le Document a été correctement parsé
>>>>>> m_bDocumentParsed = true;
>>>>>> // on retourne l'ElementXML ainsi créé
>>>>>> return m_poElementXML;
>>>>>> }
>>>>>> catch(XMLException& XMLEx)
>>>>>> {
>>>>>> l_pcMessage = XMLString::transcode(XMLEx.getMessage());
>>>>>> ExceptMessage ex("T00500", "XML Exception", l_pcMessage);
>>>>>> XMLString::release(&l_pcMessage);
>>>>>> ex.doThrow();
>>>>>> }
>>>>>> catch(DOMException& DOMEx)
>>>>>> {
>>>>>> l_pcMessage = XMLString::transcode(DOMEx.msg);
>>>>>> ExceptMessage ex("T00501", "XML Exception", l_pcMessage);
>>>>>> XMLString::release(&l_pcMessage);
>>>>>> ex.doThrow();
>>>>>> }
>>>>>> catch(SAXParseException& SaxParseEx)
>>>>>> {
>>>>>> l_pcMessage = XMLString::transcode(SaxParseEx.getMessage());
>>>>>> ExceptMessage ex("T00502", "SAXParse Exception", l_pcMessage);
>>>>>> XMLString::release(&l_pcMessage);
>>>>>> ex.doThrow();
>>>>>> }
>>>>>> catch(SAXException& SaxEx)
>>>>>> {
>>>>>> l_pcMessage = XMLString::transcode(SaxEx.getMessage());
>>>>>> ExceptMessage ex("T00502", "SAX Exception", l_pcMessage);
>>>>>> XMLString::release(&l_pcMessage);
>>>>>> ex.doThrow();
>>>>>> }
>>>>>> catch(...)
>>>>>> {
>>>>>> ExceptMessage ex("T00450", " ", "Erreur inconnue");
>>>>>> ex.doThrow();
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> You just can't imagine how happy will I be when I won't have to code
>>>>>> into
>>>>>> this libraby :D
>>>>>> Anyway, as always, if you find something weird, or even the tinniest
>>>>>> clue,
>>>>>> please, post here.
>>>>>>
>>>>>> Thanks a lot.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: [email protected]
>>>>> For additional commands, e-mail: [email protected]
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: [email protected]
>>> For additional commands, e-mail: [email protected]
>>>
>>>
>>>
>>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>
>
--
View this message in context:
http://www.nabble.com/Core-Dump-while-releasing-Parser-ressources...-tp23560721p23593714.html
Sent from the Xerces - C - Dev mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]