You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-dev@xerces.apache.org by Ramanjaneyulu malisetti <ra...@hotmail.com> on 2008/06/08 04:01:19 UTC

RE: calling Initialize/Terminate from a static object generates mem leaks

Hi costin,
                 I think you can solve this problem by creating objects in proper order. For instance, first you declare global object  of dom_initialiser and followed by static variables declaration.
 
Regards
Raman 
> From: costin.iordache@scytl.com> To: c-users@xerces.apache.org> CC: c-dev@xerces.apache.org> Subject: FW: calling Initialize/Terminate from a static object generates mem leaks> Date: Wed, 28 May 2008 17:21:09 +0200> > 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. > > > ---------------------------------------------------------------------> To unsubscribe, e-mail: c-dev-unsubscribe@xerces.apache.org> For additional commands, e-mail: c-dev-help@xerces.apache.org> 
_________________________________________________________________
Catch the latest fashion shows, get beauty tips and learn more on fashion and lifestyle.
http://video.msn.com/?mkt=en-in