문제

나는 함께 놀았다 Xerces-C XML 라이브러리.

나는 내가 가지고 놀고있는이 간단한 예제가있다.

메모리를 누출하지 않고 Segfaulting없이 실행할 수없는 것 같습니다. 하나 또는 다른 것입니다.

Segfault는 항상 "Clean Up"에서 파서 객체를 삭제할 때 항상 발생합니다.

라이브러리의 2.8 및 2.7 버전을 모두 사용해 보았습니다.

메모: 나는 코드에서 체크 아웃하는 모든 예외를 가져 갔다. 나는 그것과 동일한 결과를 얻지 못했다. 가독성과 단순성을 위해 아래 코드에서 제거했습니다.

Xerces에 정통한 사람들이 몇 가지 제안을하기 위해 관심을 갖고 있습니까?

나는 뒷 흔적에서 많은 것을 말할 수 없다. 그것은 단지 슈퍼 클래스 파괴자로 뛰어 들어 그곳에서 segfaulting입니다.

백트레이스 :

(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-> release ();"는 범인입니다. "XMLPARSER-> ANDICALTDOCUMENT ()"라고 말하지 않는 한 해당 노드를 소유하지 않습니다.

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

다른 팁

증거를 탐구합시다 ...

#6  0x95c5a14b in std::terminate ()

소멸자가 예외를 던질 때 이것이 호출되었다고 말할 수 있습니다. 예외를 던지는 소멸자는 큰 금지입니다. Xerces는 Winky를하고있을 수 있습니다.

또는이 라인으로 인해 발생할 수 있습니다

#7  0x95c5a6da in __cxa_pure_virtual ()

가상 함수 테이블에서 무언가가 누락 될 수있는 곳. 아마도 DOM Object의 멤버 파괴자 중 하나인가? 아마도 이것은 예외를 생성합니까?

이 링크 가상 테이블 조회가 실패 할 수있는 원인에 대한 훌륭한 설명을 제공합니다. 요컨대, 그것은 그 포인터에 다형성 기능을 호출하려고하는 누군가 주위에 매달려있는 기본 클래스 포인터로 인해 발생할 수 있습니다.

위의 링크에서 제공된 예 :

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

당신이 파괴하는 순서가 잘못되었고 위의 문제 중 일부를 유발할 수 있습니까? 그것의 얼굴에, 상황은 괜찮아 보이지만, 그것이 내가 실험하고 어떻게 찢어 지는지에 대한 문서를 다시 확인하고 두 번 확인할 곳입니다.

코드에 분명히 잘못된 것을 볼 수 없습니다. 코드에서 New & Delete의 모든 용도를 제거하고 대신 스택 기반 Objectys로 사용하는 CERCES 객체를 만들려고 할 수 있습니다. 예를 들어 : 대신 :

xmlParser = new XercesDOMParser();

사용:

XercesDOMParser xmlParser;

등등.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top