Search code examples
c++shared-ptrxerces-c

C++ Xerces-c: Initializing a shared_ptr


I am new to shared pointers and was wondering how to initalize a shared pointer if it is also a member variable?

Currently my code looks something like this: In the header file, I have:

class Parser {
   public:
      Parser();
      ~Parser();

      boost::shared_ptr<XercesDOMParser> parser;
{

In the constructor, I have something like this:

Parser::Parser() 
{
   try {
      XMLPlatformUtils::Initialize(); 
   } catch (...) {}

   parser = shared_ptr<XercesDOMParser> (new XercesDomParser()); 
}

In the destructor I have:

Parser::~Parser() {
   try {
      XMLPlatformUtils::Terminate();
   }catch(...) {}
}

However compiling the program with Valgrind, I would receive the following error: Pure virtual method called. Terminated without an active exception. Invalid read of size 8.

Any insights into what I may be doing incorrectly with the initialization?

My suspicion is I am reading from unallocated memory.

EDIT:

So in the destructor, I added the following lines of code before the terminate command and the memory leaks and errors all disappeared!

if (parser) parser.reset();

Why does all reference to the parser have to be gone before it can be deallocated?

Much appreciated, thanks.


Solution

  • You are calling XMLPlatformUtils::Terminate() before calling the destructor for XercesDomParser. Destructors for member variables are called after the destructor body runs. Member variables are constructed in order of declaration, and destroyed in reverse.

    You could do something like this:

    class Parser : boost::noncopyable {
        struct XmlHandle {
            XmlHandle() { XMLPlatformUtils::Initialize(); }
            ~XmlHandle() { XMLPlatformUtils::Terminate(); }
        };
    
        XmlHandle m_handle;
        boost::shared_ptr<XercesDOMParser> m_parser;
    
    public:
        Parser() : m_parser(new XercesDomParser) { }
    };
    

    And just use the default destructor. If you want copy constructors and assignment operators you'll need to deal with that.

    Oh, and catching and throwing away exceptions is probably a bad idea ...