سؤال

لقد كنت ألعب مع Xerces-C. مكتبة XML.

لدي هذا المثال البسيط الذي ألعب به.

لا أستطيع أن أحصل عليه للتشغيل دون تسريب الذاكرة وبدون segfaulting. انها واحدة أو أخرى.

يحدث Segfault دائما عند حذف كائن المحلل تحت "التنظيف".

لقد حاولت استخدام إصدارات 2.8 و 2.7 من المكتبة.

ملحوظة: أخذت كل الاستثناء عند التحقق من التعليمات البرمجية، أحصل على نفس النتائج معها وبدون ذلك. للحصول على قابلية القراءة والبساطة التي قمت بإزالتها من التعليمات البرمجية أدناه.

أي شخص Savvy Savvy هناك يهتم بإجراء بعض الاقتراحات؟

لا أستطيع أن أخبر الكثير عن التتبع الخلفي، فهذا مجرد قفز إلى Duplassor Superclass و Segfaulting هناك.

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

الرمز:

#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;
}
هل كانت مفيدة؟

المحلول

"xmldoc-> الإصدار ()؛" هو الجاني. أنت لا تملك هذه العقدة إلا إذا قلت "XMLPARSER-> اعتمادك ()"

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

نصائح أخرى

يتيح استكشاف الأدلة ...

#6  0x95c5a14b in std::terminate ()

أستطيع أن أقول لك هذا يسمى عندما يلقي المدمر استثناء. المدمرين يرمون الاستثناءات هو رقم كبير لا. Xerces قد تفعل شيئا متزعزع.

أو قد يكون سبب هذا الخط

#7  0x95c5a6da in __cxa_pure_virtual ()

حيث قد يكون هناك شيء ما في مفقود في جدول وظيفة افتراضية. ربما أحد أعضاء كائن DOM Destructor؟ ربما هذا يولد استثناء؟

هذا الرابط يقدم تفسيرا رائعا حول ما قد يؤدي إلى فشل البحث عن الجدول الظاهري. باختصار، يمكن أن يكون سبب وجود مؤشر من فئة الأساس المتدلية معلقة حول شخص يحاول إجراء مكالمة وظيفة متعددة الأشكال على هذا المؤشر.

مثال معين من الرابط أعلاه:

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

التحدث عن المؤشرات المتدلية، يبدو أن Xercesdomparser يحتجز الأشياء التي قامت بها حديثي:

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

ولكن في وقت لاحق حذف / صدر

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

هل يمكن أن يكون النظام الذي تقوم بتدمير الأشياء غير صحيحة ويسبب بعض المشاكل المذكورة أعلاه؟ على وجهها، تبدو الأمور على ما يرام، ولكن هذا هو المكان الذي أجرته وتأكد مرة أخرى من الوثائق حول كيفية مزق الأمور.

لا أستطيع أن أرى أي شيء خطأ واضح في التعليمات البرمجية. قد ترغب في محاولة إزالة جميع استخدامات جديدة والحذف في التعليمات البرمجية وإنشاء كائنات Cerces التي تستخدمها كجكائن قائمة على المكدس بدلا من ذلك. على سبيل المثال، بدلا من:

xmlParser = new XercesDOMParser();

استعمال:

XercesDOMParser xmlParser;

وما إلى ذلك وهلم جرا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top