Question

J'ai joué avec la bibliothèque XML Xerces-C .

J'ai cet exemple simple que je joue avec.

Je ne peux pas sembler l'obtenir pour fonctionner sans fuite de mémoire et sans segfaulting. C'est l'un ou l'autre.

Le segfault se produit toujours lorsque je supprime l'objet analyseur sous « Nettoyer ».

Je l'ai essayé d'utiliser les deux 2.8 et 2.7 versions de la bibliothèque.

Remarque: Je pris tous l'exception vérifier du code, je reçois les mêmes résultats avec et sans elle. Pour plus de lisibilité et de simplicité je l'ai retiré du code ci-dessous.

Les personnes Xerces-savvy soins là-bas pour faire quelques suggestions?

Je ne peux pas dire vraiment beaucoup de la trace en arrière, il est juste en sautant dans la destructor et superclasse segfaulting là.

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

Le 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;
}
Était-ce utile?

La solution

"release () xmlDoc->;" est le coupable. Vous ne possédez pas ce nœud, sauf si vous dites "xmlParser-> adoptDocument ()"

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

Autres conseils

permet d'explorer les éléments de preuve ...

#6  0x95c5a14b in std::terminate ()

Je peux vous dire ceci est appelé lorsqu'un destructor lance une exception. Destructeurs lancer des exceptions est un gros no-no. Xerces peut faire quelque chose de bancal.

Ou il pourrait être causé par cette ligne

#7  0x95c5a6da in __cxa_pure_virtual ()

où quelque chose peut-être manquant dans une table de fonction virtuelle. Peut-être l'un des membres de l'objet DOM de destructor? Peut-être que cela génère une exception?

Ce lien offre une grande explication sur ce qui pourrait provoquer des recherches de table virtuelle à échouer. En bref, elle peut être causée par un pointeur de classe de base ballants traîner quelqu'un qui essaie de faire un appel de fonction polymorphes sur ce pointeur.

Exemple donné ci-dessus à partir du lien:

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

En parlant de pointeurs ballants, il semble que le XercesDomParser tient objets newed:

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

mais plus tard supprimé / libéré

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

pourrait l'ordre que vous détruisez les choses soient incorrectes et causer certains des problèmes ci-dessus? Sur le visage de celui-ci, les choses sont OK, mais c'est où j'expérimenter et vérifier la documentation sur la façon dont les choses sont censées être démolis.

Je ne vois rien de mal avec le évidemment code. Vous pouvez essayer de retirer toutes les utilisations des nouvelles et supprimer dans le code et créer les objets Cerces utilisez vous objectys à base de pile à la place. Par exemple, au lieu de:

xmlParser = new XercesDOMParser();

utilisation:

XercesDOMParser xmlParser;

et ainsi de suite.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top