Frage

Ich habe das Spiel mit der Xerces-C XML-Bibliothek.

Ich habe dieses einfache Beispiel mit ich spiele.

kann ich nicht scheinen, um es ohne undichten Speicher zu laufen zu bekommen und ohne Speicherzugriffsfehler. Es ist das eine oder das andere.

Die segfault tritt immer dann auf, wenn ich das Parser-Objekt unter löschen „Clean up“.

Ich habe versucht mit sowohl die 2.8 & 2.7 Versionen der Bibliothek.

Hinweis: ich alle Ausnahme nahm aus dem Code überprüft, erhalte ich die gleichen Ergebnisse mit ihr und ohne sie. Zur besseren Lesbarkeit und Einfachheit entfernte ich es aus dem Code unten.

Jede Xerces versiert Leute da draußen kümmern einige Vorschläge machen?

Ich kann nicht wirklich viel von der Rückseite Spur sagen, es springt nur nach unten in den Super destructor und dort Speicherzugriffsfehler.

Backtrace:

(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;
}
War es hilfreich?

Lösung

"xmlDoc-> Release ();" ist der Schuldige. Sie nicht, dass der Knoten besitzen, wenn Sie sagen: "xmlParser-> adoptDocument ()"

http://xerces.apache.org/xerces c / apidocs-2 / classAbstractDOMParser.html # fe052561c37d70b62ac57ab6706d75aa

Andere Tipps

Hier können die Beweise erkunden ...

#6  0x95c5a14b in std::terminate ()

Ich kann Ihnen sagen, das aufgerufen wird, wenn ein destructor eine Ausnahme auslöst. Destructors Ausnahmen zu werfen ist eine große No-No. Xerces kann, etwas zu tun wackelig sein.

Oder es könnte durch diese Linie verursacht werden

#7  0x95c5a6da in __cxa_pure_virtual ()

, wo etwas könnte in einer virtuellen Funktionstabelle fehlen. Vielleicht ist einer der Mitglieder destructor DOM-Objekt? Vielleicht ist dies erzeugt eine Ausnahme?

Dieser Link eine große Erklärung bietet, was die virtuelle Tabelle Lookups könnte dazu führen, Scheitern. Kurz gesagt, kann es durch einen baumelnde Basisklasse Zeiger verursacht wird rumhängen jemand versucht, einen polymorphen Funktionsaufruf auf diesem Zeiger zu machen.

Beispiel aus dem Link oben angegebene:

// From sample program 5:
AbstractShape* p1 = new Rectangle(width, height, valuePerSquareUnit);
std::cout << "value = " << p1->value() << std::endl;
AbstractShape* p2 = p1;  // Need another copy of the pointer.
delete p1;
std::cout << "now value = " << p2->value() << std::endl;

Apropos baumelnden Zeigern, es sieht aus wie die XercesDomParser ist Objekte halten Sie newed:

  errHandler = (ErrorHandler*) new HandlerBase();
  xmlParser->setErrorHandler( errHandler )

aber später gelöscht / freigegeben

  // Clean up
  XMLString::release( &xmlMetadata );
  xmlDoc->release();
  delete xmlParser;
  delete memBufIS;
  delete errHandler;

Könnte die Reihenfolge Sie zerstören Dinge falsch sein und einige der oben genannten Probleme verursachen? Auf den ersten Blick scheint, sieht es in Ordnung, aber das ist, wo ich experimentieren würde und überprüfen Sie die Dokumentation auf, wie die Dinge sollen abgerissen werden.

Ich kann nichts offensichtlich falsch mit dem Code. Sie könnten versuchen, sich bei allen Anwendungen von neuen Entfernen & im Code löschen und die Cerces erstellen Objekte, die Sie Stack basiert objectys verwenden, wie statt. Zum Beispiel statt:

xmlParser = new XercesDOMParser();

Verwendung:

XercesDOMParser xmlParser;

und so weiter.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top