Compiler reports memory leaks in VC++

Liquid XML Data Binding use smart pointers to avoid the possibility of memory leaks. Each object is referenced counted and automatically deleted as it drops from scope so you should not experience memory leaks.

1. Static Class Data

Generated classes declare static data for use by the base classes in order to serialize the data. This static data is only destroyed with the application and should not be considered a leak as they are only be created once and are destroyed at application termination. The 'leaks' are seen by the Microsoft VC++ memory tracking as leaks as they are not cleared until the application terminates (i.e. after the memory tracking code is called).

You can call the
CleanMetaData static methods from each CClassFactory class (one for each namespace) to remove static data from all the generated classes at the end of your application: E.g.

namespaceA::CClassFactory::CleanMetaData();
namespaceB::CClassFactory::CleanMetaData();
etc.


2. Object Tracking in Debug

In debug mode, liquid tracks object creation and deletions so it can display any instances not deleted, in other words it does its own memory leak detection.

On Microsoft platforms memory tracking is already supplied by the C runtimes. However, liquid is designed to run on many other platforms so the mechanism needs to be platform independent.

In debug when an object is created it is registered with a memory monitor, and un registered when its destroyed, this takes up a little extra time, and causes entries to be added to a static list. The contents of this list are then dumped at the end of the application.

A problem can occur on VC++ platforms which results in the compiler reporting a leak that does not exist. This is because the compiler has performed its memory leak checking before the lists associated with the liquid memory tracker are freed up. Liquids memory tracking lists are then flagged up as memory leaks

This results in a dump that looks like this

Detected memory leaks!
Dumping objects ->
{292} normal block at 0x003D9EB8, 12 bytes long.
Data: 41 42 42 20 53 63 68 77 65 69 7A 00
{291} normal block at 0x003D9E60, 20 bytes long.
Data: < PA = > C0 50 41 00 B8 9E 3D 00 00 CD FF FF 00 02 00 00
{290} normal block at 0x003D9E18, 12 bytes long.
Data: 41 42 42 20 53 63 68 77 65 69 7A 00
{289} normal block at 0x003D9DC0, 20 bytes long.
Data: < PA = > C0 50 41 00 18 9E 3D 00 00 CD FF FF 00 02 00 00


This can be worked around by explicitly calling the cleanup routines at the end of your application.

#include "MemoryLeakHelp.h"

...

OutputDebugString(_T("Dumping Class instances\n"));
OutputDebugString(CInstanceMonitor::DumpState().c_str());
OutputDebugString(_T("\n"));
CInstanceMonitor::Cleanup();



NOTE:
It is important to note that this code will be removed by the compiler in release builds.