wxXmlNamespace instances are factoried via static
methods of wxXmlNamespace. This is done for
efficiency. A lot of references to namespaces are
created during the lifetime of any wxXmlElement or
wxXmlAttribute. Using a factory is faster and more
memory efficient than instantiated many namespace
references.
On the other hand, these singleton instances are
currently never freed, so memory is leaked during the
lifetime of any wxXml client application.
I believe leaked wxXmlNamespace instances is
responsible for all the memory leaked in the testapp.
Proposed Solutions:
1) Reference count wxXmlNamespace instances. We
could use a Clone() method to spawn a new reference
to a namespace:
wxXmlNamespace* wxXmlNamespace::Clone();
We could also simply increment the reference count
every time wxXmlNamespace::GetNamespace() is
invoked.
Then, every time a reference to a wxXmlNamespace
instance is no longer needed, the following function is
called:
void wxXmlNamespace::Release();
Once the reference count of a namespace goes to zero,
the instance is finally deleted.
The drawback of this solution is that client applications
cannot just assign copies of references to these
instances. Also, client application developers (us) must
remember to Release() references when they're no
longer needed.
2) Another solution, which is less elegant, but simpler to
implement, is to wrap all wxXml client code inside a pair
of calls to Initialize() and Release() functions. These
would be static functions of wxXmlNamespace:
static void wxXmlNamespace::Initialize();
static void wxXmlNamespace::Release();
The Release() function simply frees all wxXmlNamespace
instances that have been factoried. This solution is a
little dangerous because it doesn't account for if there
are still wxXmlElement or wxXmlAttribute instances
floating around referring to these namespaces that we
just destroyed!
This implementation allows for creating wxXmlNamespace
instances as static const class members. This is
frequently desirable. For example, for the Jabber API, we
might want to declare the following member of wxJabber:
static const wxXmlNamespace* JABBER_CLIENT_NS;
Then, we would define and instantiation the reference:
static const wxXmlNamespace*
wxJabber::JABBER_CLIENT_NS =
wxXmlNamespace::GetNamespace("jabber:client", "");
Then, anytime code wants to refer to the Jabber client
namespace, they simply do this:
wxJabber::JABBER_CLIENT_NS
They do not have to do this, like solution (1) would
require:
wxJabber::JABBER_CLIENT_NS->Clone()