Statisches Attribut sorgt für Segmentation Fault vor (!) der Main
-
Hallo,
beim Erstellen eines geeigneten Parsers mit der Apache Xerces Bibliothek (SAX) für ein bestimmtes XML-Format ist mir eine bisher noch nicht begegnete Eigenart in C++ (oder gar Xerces?) untergekommen. Wenn ich Attribute des Typs XercesString (Entnommen aus http://www.ibm.com/developerworks/xml/library/x-xercc/) in meinem eigenen Handler (erbt von der Xerces-Klasse "DefaultHandler") als statisch deklariere, erhalte ich nach erfolgreichem Kompilieren und Starten einen Segmentation Fault, der vor (!) der Main-Funktion auftritt. Sinn des Ganzen soll eine Optimierung des Codes sein. Jedenfalls funktionieren diese Attribute als nicht-statische Elemente der Klasse einwandfrei. Richtig deklariert und vor allem initialisiert sollten diese statischen Attribute sein. Jedenfalls geht es ohne Weiteres mit dem Typ std::string aus der STL. Wie kann es also sein, dass ein einzelnes statisches Attribut einen solch fatalen Fehler auslöst?
Ich bin dankbar für jede Antwort!

#ifndef XERCESSTRING_H_ #define XERCESSTRING_H_ #include <util/XMLString.hpp> namespace Utils { namespace String { #ifdef XERCES_CPP_NAMESPACE_USE XERCES_CPP_NAMESPACE_USE #endif class XercesString { XMLCh *_wstr; public: XercesString() : _wstr(0L) { }; XercesString(const char *str); XercesString(XMLCh *wstr); XercesString(const XMLCh *wstr); XercesString(const XercesString ©); ~XercesString(); bool append(const XMLCh *tail); bool erase(const XMLCh *head, const XMLCh *tail); const XMLCh* begin() const; const XMLCh* end() const; int size() const; XMLCh & operator [] (const int i); const XMLCh operator [] (const int i) const; operator const XMLCh * () const { return _wstr; }; void operator = (const char *str) { _wstr = XMLString::transcode(str); } }; } } #endif /* XERCESSTRING_H_ */#include "XercesString.h" namespace Utils { namespace String { XercesString::XercesString(const char *str) : _wstr(NULL) { _wstr = XMLString::transcode(str); } XercesString::XercesString(XMLCh *wstr) : _wstr(wstr) { }; XercesString::XercesString(const XMLCh *wstr) : _wstr(NULL) { _wstr = XMLString::replicate(wstr); } XercesString::XercesString(const XercesString &right) : _wstr(NULL) { _wstr = XMLString::replicate(right._wstr); } XercesString::~XercesString() { // thanks tinny!! if (_wstr) XMLString::release(&_wstr); } bool XercesString::append(const XMLCh *tail) { int iTailLen = XMLString::stringLen(tail); int iWorkLen = XMLString::stringLen(_wstr); XMLCh *result = new XMLCh[ iWorkLen + iTailLen + 1 ]; bool bOK = result != NULL; if (bOK) { XMLCh *target = result; XMLString::moveChars(target, _wstr, iWorkLen); target += iWorkLen; XMLString::moveChars(target, tail, iTailLen); target += iTailLen; *target++ = 0; XMLString::release(&_wstr); _wstr = result; } return bOK; } bool XercesString::erase(const XMLCh *head, const XMLCh *tail) { bool bOK = head <= tail && head >= begin() && tail <= end(); if (bOK) { XMLCh *result = new XMLCh[ size() - (tail - head) + 1 ]; XMLCh *target = result; bOK = target != NULL; if (bOK) { const XMLCh *cursor = begin(); while (cursor != head) *target++ = *cursor++; cursor = tail; while ( cursor != end() ) *target++ = *cursor++; *target ++ = 0; XMLString::release(&_wstr); _wstr = result; } } return bOK; } const XMLCh* XercesString::begin() const { return _wstr; } const XMLCh* XercesString::end() const { return _wstr + size(); } int XercesString::size() const { return XMLString::stringLen(_wstr); } XMLCh & XercesString::operator [] (const int i) { return _wstr[i]; } const XMLCh XercesString::operator [] (const int i) const { return _wstr[i]; } } }#ifndef UNITHANDLER_H_ #define UNITHANDLER_H_ #include <SFML/Graphics.hpp> #include <SFML/Audio/Sound.hpp> #include <sax2/DefaultHandler.hpp> #include <boost/shared_ptr.hpp> #include <cstdlib> #include <string> #include <map> #include "../Graphics/AnimatedSprite.h" #include "../Utils/String/XercesString.h" #ifdef XERCES_CPP_NAMESPACE_USE XERCES_CPP_NAMESPACE_USE #endif using namespace Engine::Graphics; using namespace Utils::String; /* XercesString */ namespace Engine { namespace Serialization { /* * An instance of the structure sprite_set contains sprites of * a specified action of the unit including all sub sprites like * holding a weapon. */ struct action_set { std::string m_strAction; sf::Image m_image; sf::Sound m_sound; std::map<std::string, AnimatedSprite> m_sprites; action_set(std::string& strAction) : m_strAction(strAction) { }; action_set() { }; AnimatedSprite* operator[](std::string spriteKey) { return &m_sprites[spriteKey]; }; }; /* * An instance of the UnitHandler provides methods for filling * a unit using a XML file as source. Its mostly used by an in- * stance of SAX2XMLReader. */ class UnitHandler : public DefaultHandler { private: /* * Debug mode on/off */ static const bool m_bDebug = true; /* Tags */ static std::string m_strTest; /* Folgendes Attribut würde den besagten Fehler auslösen */ static const XercesString m_tstrActions; XercesString m_tstrAction; XercesString m_tstrSprite; XercesString m_tstrStart; XercesString m_tstrRun; XercesString m_tstrStop; XercesString m_tstrFrame; /* Attributes */ XercesString m_astrName; XercesString m_astrLow; XercesString m_astrNormal; XercesString m_astrHigh; XercesString m_astrSound; XercesString m_astrLeft; XercesString m_astrTop; XercesString m_astrRight; XercesString m_astrBottom; XercesString m_astrDelay; std::map<std::string, action_set>* m_pActions; std::map<std::string, action_set>::iterator m_ActionsIterator; std::map<std::string, AnimatedSprite>::iterator m_SpriteIterator; boost::shared_ptr< std::vector<Frame> > m_pTmpFrames; bool m_bUsePhysFS; /* * Boolean variables used by the XML Parser */ bool m_bFile; public: /* * Creates a new instance of UnitHandler using a given unit as * argument. The given unit will be filled with data (for example * sprites) using a xml file as source. */ UnitHandler(std::map<std::string, action_set>& actions, bool usePhysFS); virtual ~UnitHandler(); virtual void startDocument(); virtual void endDocument(); virtual void startElement( const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const Attributes& attrs); virtual void endElement( const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname); virtual void characters( const XMLCh* const chars, const unsigned int length); }; } } #endif /* UNITHANDLER_H_ */#include "UnitHandler.h" #include <sax2/Attributes.hpp> #include "../Utils/String/XercesString.h" namespace Engine { namespace Serialization { /* Initialisierung des Attributes, welches den Fehler auslöst */ const XercesString UnitHandler::m_tstrActions("actions"); UnitHandler::UnitHandler(std::map<std::string, action_set>& actions, bool usePhysFS) : m_pActions(&actions), m_bUsePhysFS(usePhysFS) { //m_tstrActions = "actions"; m_tstrAction = "action"; m_tstrSprite = "sprite"; m_tstrStart = "start"; m_tstrRun = "run"; m_tstrStop = "stop"; m_tstrFrame = "frame"; m_astrName = "name"; m_astrLow = "low"; m_astrNormal = "normal"; m_astrHigh = "high"; m_astrSound = "sound"; m_astrLeft = "left"; m_astrTop = "top"; m_astrRight = "right"; m_astrBottom = "bottom"; m_astrDelay = "delay"; } UnitHandler::~UnitHandler() { } void UnitHandler::startDocument() { if(m_bDebug) std::cout << "_start document_" << std::endl; } void UnitHandler::endDocument() { if(m_bDebug) std::cout << "_end document_" << std::endl; } void UnitHandler::startElement(const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname, const Attributes & attrs) { if(m_bDebug) std::cout << "__start Element__" << std::endl; try { if(!XMLString::compareString(localname, m_tstrAction)) { std::string strName(XMLString::transcode(attrs.getValue(m_astrName))); std::string strImage(XMLString::transcode(attrs.getValue(m_astrLow))); m_pActions->insert(std::make_pair(strName, action_set(strName))); m_ActionsIterator = m_pActions->find(strName); if(m_bUsePhysFS){ /* Load image using physicsFS [NOT IMPLEMENTED]*/ } else { m_ActionsIterator->second.m_image.LoadFromFile(strImage); m_ActionsIterator->second.m_image.CreateMaskFromColor(sf::Color(255,0,255,255), 0); } } else if(m_pActions->size()) { if(!XMLString::compareString(localname, m_tstrSprite)) { std::string strName(XMLString::transcode(attrs.getValue(m_astrName))); m_ActionsIterator->second.m_sprites.insert(std::make_pair(strName, AnimatedSprite())); m_SpriteIterator = m_ActionsIterator->second.m_sprites.find(strName); m_SpriteIterator->second.SetImage(m_ActionsIterator->second.m_image); } else if(!XMLString::compareString(localname, m_tstrRun)) { boost::shared_ptr< std::vector<Frame> > pFrames(new std::vector<Frame>()); m_pTmpFrames = pFrames; } else if(!XMLString::compareString(localname, m_tstrFrame)) { std::string strLeft(XMLString::transcode(attrs.getValue(m_astrLeft))); std::string strTop(XMLString::transcode(attrs.getValue(m_astrTop))); std::string strRight(XMLString::transcode(attrs.getValue(m_astrRight))); std::string strBottom(XMLString::transcode(attrs.getValue(m_astrBottom))); std::string strDelay(XMLString::transcode(attrs.getValue(m_astrDelay))); m_pTmpFrames->push_back(Frame(IntRect(atoi(strLeft.c_str()), atoi(strTop.c_str()), atoi(strRight.c_str()), atoi(strBottom.c_str())), static_cast<float>(atof(strDelay.c_str())))); } } } catch(std::exception &e) { std::cerr << "Caught " << e.what() << std::endl; } } void UnitHandler::characters(const XMLCh *const chars, const unsigned int length) { if(m_bDebug) std::cout << "___characters___" << std::endl; } void UnitHandler::endElement(const XMLCh *const uri, const XMLCh *const localname, const XMLCh *const qname) { if(m_bDebug) std::cout << "__end Element__" << std::endl; if(!XMLString::compareString(localname, m_tstrRun)) { m_SpriteIterator->second.SetSubRectangles(m_pTmpFrames); } } } }
-
bisschen weniger quellcode, diesen dann kommentiert....
-
Was macht XMLString::transcode? Hast du mal einen Backtrace gemacht wo genau der Segfault kommt? Abgesehen davon bin ich mit Skybrabbel einer Meinung, kürz den Code mal auf das Wesentliche.