Pregunta

He estado jugando con la C Xerces-librería XML .

Tengo este sencillo ejemplo que estoy jugando.

Me parece que no puede conseguir que se ejecute sin fugas de memoria y sin violación de segmento. Es una u otra.

La violación de segmento siempre se produce cuando se borra el objeto analizador en "limpiar".

He intentado usar tanto los 2.8 y 2.7 versiones de la biblioteca.

Nota: Tomé todos a excepción de la salida de la código, consigo los mismos resultados con ella y sin ella. Para facilitar la lectura y la sencillez que lo quité del código de abajo.

Cualquier personas con conocimientos Xerces por ahí se preocupan de hacer algunas sugerencias?

Realmente no puedo decir mucho de la traza hacia atrás, es simplemente saltar hacia abajo en el destructor superclase y la violación de segmento allí.

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

El código:

#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;
}
¿Fue útil?

Solución

"xmlDoc-> liberación ();" es el culpable. Usted no poseer ese nodo a menos que se dice "xmlParser-> adoptDocument ()"

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

Otros consejos

Vamos a explorar la evidencia ...

#6  0x95c5a14b in std::terminate ()

Yo puedo decir esto se llama cuando un destructor lanza una excepción. Los destructores lanzar excepciones es un gran no-no. Xerces pueden estar haciendo algo poco firme.

O podría ser causada por esta línea

#7  0x95c5a6da in __cxa_pure_virtual ()

donde algo puede faltar en una tabla de función virtual. Quizás uno de los miembros destructor del objeto DOM? Tal vez esto genera una excepción?

Este enlace ofrece una gran explicación sobre lo que podría hacer que las búsquedas en tablas virtuales a fallar. En resumen, puede ser causada por un puntero de la clase base colgando colgando alrededor de alguien que intenta hacer una llamada a la función polimórfica en ese puntero.

Ejemplo dada desde el enlace de arriba:

// 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;

Hablando de referencia colgante, parece que el XercesDomParser está sosteniendo objetos newed:

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

pero más tarde borrado / liberado

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

Podría el orden en que están destruyendo las cosas sean incorrectas y causar algunos de los problemas anteriores? En vista de ello, las cosas se ven bien, pero ahí es donde me gustaría experimentar y vuelva a comprobar la documentación sobre cómo las cosas tienen que ser derribado.

No puedo ver nada, obviamente mal con el código. Usted puede intentar la eliminación de todos los usos de nuevo y borrar el código y crear los objetos Cerces utiliza como base objectys pila en su lugar. Por ejemplo, en lugar de:

xmlParser = new XercesDOMParser();

uso:

XercesDOMParser xmlParser;

y así sucesivamente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top