Ich habe mich mit der Xerces-C XML-Bibliothek.
Ich habe dieses einfache Beispiel, mit dem ich spiele.
Ich kann es nicht zum Laufen bringen, ohne dass Speicher verloren geht und ohne dass es zu Segfehlern kommt. Es ist entweder das eine oder das andere.
Der Segfault tritt immer auf, wenn ich das Parser-Objekt unter "Aufräumen" lösche.
Ich habe versucht, sowohl die 2.8- als auch die 2.7-Version der Bibliothek zu verwenden.
Anmerkung: Ich habe die gesamte Ausnahmeprüfung aus dem Code entfernt und erhalte mit und ohne sie die gleichen Ergebnisse. Für Lesbarkeit und Einfachheit habe ich es aus dem Code unten entfernt.
Kann jemand, der sich mit Xerces auskennt, einige Vorschläge machen?
Ich kann nicht wirklich viel von der Rückverfolgung sagen, es ist nur Springen nach unten in die Superklasse Destruktor und Segfaulting dort.
Zurückverfolgen:
(gdb) bt
#0 0x9618ae42 in __kill ()
#1 0x9618ae34 in kill$UNIX2003 ()
#2 0x961fd23a in raise ()
#3 0x96209679 in abort ()
#4 0x95c5c005 in __gnu_cxx::__verbose_terminate_handler ()
#5 0x95c5a10c in __gxx_personality_v0 ()
#6 0x95c5a14b in std::terminate ()
#7 0x95c5a6da in __cxa_pure_virtual ()
#8 0x003e923e in xercesc_2_8::AbstractDOMParser::cleanUp ()
#9 0x003ead2a in xercesc_2_8::AbstractDOMParser::~AbstractDOMParser ()
#10 0x0057022d in xercesc_2_8::XercesDOMParser::~XercesDOMParser ()
#11 0x000026c9 in main (argc=2, argv=0xbffff460) at test.C:77
Der Code:
#include <string>
#include <vector>
#if defined(XERCES_NEW_IOSTREAMS)
#include <iostream>
#else
#include <iostream.h>
#endif
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
using namespace std;
XERCES_CPP_NAMESPACE_USE
int main(int argc, char const* argv[])
{
string skXmlMetadata = "<?xml version=\"1.0\"?>\n <xmlMetadata>b</xmlMetadata>";
XMLPlatformUtils::Initialize();
XercesDOMParser* xmlParser = NULL;
DOMWriter* xmlWriter = NULL;
ErrorHandler* errHandler = NULL;
const XMLByte* xmlBuf = NULL;
MemBufInputSource* memBufIS = NULL;
DOMNode* xmlDoc = NULL;
xmlParser = new XercesDOMParser();
xmlParser->setValidationScheme( XercesDOMParser::Val_Never );
xmlParser->setDoNamespaces( false );
xmlParser->setDoSchema( false );
xmlParser->setLoadExternalDTD( false );
errHandler = (ErrorHandler*) new HandlerBase();
xmlParser->setErrorHandler( errHandler );
// Create buffer for current xmlMetadata
xmlBuf = (const XMLByte*) skXmlMetadata.c_str();
const char* bufID = "XmlMetadata";
memBufIS = new MemBufInputSource( xmlBuf, skXmlMetadata.length(), bufID, false );
// Parse
xmlParser->resetErrors();
xmlParser->parse( *memBufIS );
xmlDoc = xmlParser->getDocument();
// Write created xml to input SkArray
XMLCh* metadata = NULL;
xmlWriter = DOMImplementation::getImplementation()->createDOMWriter();
xmlWriter->setFeature( XMLUni::fgDOMWRTFormatPrettyPrint, true );
metadata = xmlWriter->writeToString( *xmlDoc );
xmlWriter->release();
// Print out our parsed document
char* xmlMetadata = XMLString::transcode( metadata );
string c = xmlMetadata;
cout << c << endl;
// Clean up
XMLString::release( &xmlMetadata );
xmlDoc->release();
delete xmlParser; // Dies here
delete memBufIS;
delete errHandler;
XMLPlatformUtils::Terminate();
return 0;
}