Hi,

I'm using xerces 2.7 on Windows XP SP3, Visual Studio 2003. Everything was
fine until I needed to declare a static variable (at file scope) which, in
turn, contained references to xerces objects that need xercesc_2_7
::Initialize/ xercesc_2_7::Terminate pair functions to be called first.
Thus, I had to find a way to call xercesc_2_7::Initialize before entering
main function. Here is my file:

#include <xercesc/util/PlatformUtils.hpp>

struct dom_initialiser
{
        dom_initialiser ()
        {
                xercesc_2_7::XMLPlatformUtils::Initialize();
        }

        ~ dom_initialiser ()
        {
                xercesc_2_7::XMLPlatformUtils::Terminate();
        }
};

dom_initialiser t; 

int main(int argc, char* argv[])
{
        return 0;
}



Although the program is trivial, Rational Purify reports memory leaks! I
investigated to see how serious the warnings/memory leaks are and I
discovered the following:

1. xerces uses XMLRegisterCleanup to clean up some stuff. Static objects of
type XMLRegisterCleanup are instantiated through xerces cpp files and
XMLRegisterCleanup::registerCleanup method is afterwards called to register
pointers to functions that will do the actual clean up. Internally, the
class holds two pointers which serve to implement a doubly linked list,
gXMLCleanupList. 

2. XMLPlatformUtils::Terminate() (platformsutils.cpp file) method iterates
over gXMLCleanupList and calls doCleanup(). 



The problem with this approach is that some of (all) the static objects are
used BEFORE their initialization! That's the reason why rational purify
detects memory leaks! For instance, in file TransService.cpp the objects

static XMLRegisterCleanup mappingsCleanup;
static XMLRegisterCleanup mappingsRecognizerCleanup;

are used in the constructor XMLTransService::XMLTransService() before their
initialization (lines 94, 107):

 mappingsCleanup.registerCleanup(reinitMappings);  // mappingsCleanup not
initialized!!!!


I solved this by creating a new function(s):
XMLRegisterCleanup & mappingsCleanup()
{
        static XMLRegisterCleanup mappingsCleanup;
        return mappingsCleanup;
}
and calling mappingsCleanup().registerCleanup(reinitMappings);


Question: do you think guys that this approach is ok? Can you spot any
hidden issue that is not so obvious? Do you think that it would be a good
idea to change all static instances of XMLRegisterCleanup objects to
functions?


If you look inside the file XMLRegisterCleanup.hpp there is a comment
saying:

"//  N.B. These objects need to be statically allocated.  I couldn't think
//  of a neat way of ensuring this - can anyone else?"



That is all with the static construction. Now, let's move on destruction: 

xercesc_2_7::XMLPlatformUtils::Terminate() must be called last. Therefore, I
isolated struct test into an hpp that is included FIRST by any project hpp
that uses xerces. The files (hpp and cpp) look like this:


########################################dom_init.hpp#####################

#ifndef DOM_INIT_HPP
#define DOM_INIT_HPP

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

    };

        namespace 
        {
                /**
                * Dummy object that forces the creation of dom_initialiser.
                * This will ensure that creating static or file scope
                * instances of xml::str is not done before the XML lib is
                * properly initialised AND XMLPlatformUtils::Terminate() is
called
                        last (after all xerce objects have been destroyed) 
                */

                dom_initialiser __dummy__dom_initialiser__;
        }
#endif



#########################dom_init.cpp#########################

#include "dom_init.hpp"
using namespace xercesc;        

dom_initialiser::dom_initialiser()
{
        XMLPlatformUtils::Initialize();
}

dom_initialiser::~dom_initialiser()
{
        XMLPlatformUtils::Terminate();
}

With this approach I completely eliminated the need of explicit call to
Initialize/Terminate! 



Please feel free to criticize. Any comments are welcomed!


Costin. 

Reply via email to