From 5b0a6777120536a527009d70dc905cc0d00da861 Mon Sep 17 00:00:00 2001 From: Lee Thomason Date: Mon, 19 Nov 2012 13:54:42 -0800 Subject: [PATCH] fix incorrect assert on unused memory --- tinyxml2.cpp | 18 ++++++++++++++---- tinyxml2.h | 21 ++++++++++++++++----- tinyxml2.sln | 20 +++++++------------- xmltest.cpp | 14 +++++++++++++- 4 files changed, 50 insertions(+), 23 deletions(-) diff --git a/tinyxml2.cpp b/tinyxml2.cpp index 538717a..fa91b5d 100755 --- a/tinyxml2.cpp +++ b/tinyxml2.cpp @@ -669,6 +669,7 @@ XMLNode* XMLNode::InsertEndChild( XMLNode* addThis ) addThis->_next = 0; } addThis->_parent = this; + addThis->_memPool->SetTracked(); return addThis; } @@ -693,6 +694,7 @@ XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis ) addThis->_next = 0; } addThis->_parent = this; + addThis->_memPool->SetTracked(); return addThis; } @@ -713,6 +715,7 @@ XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ) afterThis->_next->_prev = addThis; afterThis->_next = addThis; addThis->_parent = this; + addThis->_memPool->SetTracked(); return addThis; } @@ -814,6 +817,7 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEnd ) if ( parentEnd ) { *parentEnd = static_cast(node)->_value; } + node->_memPool->SetTracked(); // created and then immediately deleted. DELETE_NODE( node ); return p; } @@ -1314,6 +1318,7 @@ XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name ) _rootAttribute = attrib; } attrib->SetName( name ); + attrib->_memPool->SetTracked(); // always created and linked. } return attrib; } @@ -1355,6 +1360,7 @@ char* XMLElement::ParseAttributes( char* p ) if ( XMLUtil::IsAlpha( *p ) ) { XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); attrib->_memPool = &_document->_attributePool; + attrib->_memPool->SetTracked(); p = attrib->ParseDeep( p, _document->ProcessEntities() ); if ( !p || Attribute( attrib->Name() ) ) { @@ -1508,10 +1514,14 @@ XMLDocument::~XMLDocument() attributePool.Trace( "attribute" ); #endif - TIXMLASSERT( _textPool.CurrentAllocs() == 0 ); - TIXMLASSERT( _elementPool.CurrentAllocs() == 0 ); - TIXMLASSERT( _commentPool.CurrentAllocs() == 0 ); - TIXMLASSERT( _attributePool.CurrentAllocs() == 0 ); +#ifdef DEBUG + if ( Error() == false ) { + TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() ); + TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() ); + TIXMLASSERT( _textPool.CurrentAllocs() == _textPool.Untracked() ); + TIXMLASSERT( _commentPool.CurrentAllocs() == _commentPool.Untracked() ); + } +#endif } diff --git a/tinyxml2.h b/tinyxml2.h index d025ecd..1ffbfa3 100755 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -45,7 +45,7 @@ distribution. */ /* gcc: - g++ -Wall tinyxml2.cpp xmltest.cpp -o gccxmltest.exe + g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe Formatting, Artistic Style: AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h @@ -98,9 +98,9 @@ inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) #define TIXML_SSCANF sscanf #endif -static const int TIXML2_MAJOR_VERSION = 1; -static const int TIXML2_MINOR_VERSION = 0; -static const int TIXML2_PATCH_VERSION = 9; +static const int TIXML2_MAJOR_VERSION = 1; +static const int TIXML2_MINOR_VERSION = 0; +static const int TIXML2_PATCH_VERSION = 9; namespace tinyxml2 { @@ -285,6 +285,7 @@ public: virtual int ItemSize() const = 0; virtual void* Alloc() = 0; virtual void Free( void* ) = 0; + virtual void SetTracked() = 0; }; @@ -295,7 +296,7 @@ template< int SIZE > class MemPoolT : public MemPool { public: - MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0) {} + MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {} ~MemPoolT() { // Delete the blocks. for( int i=0; i<_blockPtrs.Size(); ++i ) { @@ -330,6 +331,7 @@ public: _maxAllocs = _currentAllocs; } _nAllocs++; + _nUntracked++; return result; } virtual void Free( void* mem ) { @@ -349,6 +351,14 @@ public: name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() ); } + void SetTracked() { + _nUntracked--; + } + + int Untracked() const { + return _nUntracked; + } + enum { COUNT = 1024/SIZE }; // Some compilers do not accept to use COUNT in private part if COUNT is private private: @@ -365,6 +375,7 @@ private: int _currentAllocs; int _nAllocs; int _maxAllocs; + int _nUntracked; }; diff --git a/tinyxml2.sln b/tinyxml2.sln index af8daa5..69dadf1 100644 --- a/tinyxml2.sln +++ b/tinyxml2.sln @@ -1,24 +1,18 @@  -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyxml2", "tinyxml2\tinyxml2.vcxproj", "{16A1D446-5415-444E-A7B4-F35B7DA7EE8C}" +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyxml2", "tinyxml2.vcproj", "{74F44A96-0BB5-416F-AA93-27A1DACB4234}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 - Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {16A1D446-5415-444E-A7B4-F35B7DA7EE8C}.Debug|Win32.ActiveCfg = Debug|Win32 - {16A1D446-5415-444E-A7B4-F35B7DA7EE8C}.Debug|Win32.Build.0 = Debug|Win32 - {16A1D446-5415-444E-A7B4-F35B7DA7EE8C}.Debug|x64.ActiveCfg = Debug|x64 - {16A1D446-5415-444E-A7B4-F35B7DA7EE8C}.Debug|x64.Build.0 = Debug|x64 - {16A1D446-5415-444E-A7B4-F35B7DA7EE8C}.Release|Win32.ActiveCfg = Release|Win32 - {16A1D446-5415-444E-A7B4-F35B7DA7EE8C}.Release|Win32.Build.0 = Release|Win32 - {16A1D446-5415-444E-A7B4-F35B7DA7EE8C}.Release|x64.ActiveCfg = Release|x64 - {16A1D446-5415-444E-A7B4-F35B7DA7EE8C}.Release|x64.Build.0 = Release|x64 + {74F44A96-0BB5-416F-AA93-27A1DACB4234}.Debug|Win32.ActiveCfg = Debug|Win32 + {74F44A96-0BB5-416F-AA93-27A1DACB4234}.Debug|Win32.Build.0 = Debug|Win32 + {74F44A96-0BB5-416F-AA93-27A1DACB4234}.Release|Win32.ActiveCfg = Release|Win32 + {74F44A96-0BB5-416F-AA93-27A1DACB4234}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/xmltest.cpp b/xmltest.cpp index ae318ec..152c588 100644 --- a/xmltest.cpp +++ b/xmltest.cpp @@ -1,5 +1,8 @@ -#include "tinyxml2.h" +#if defined( _MSC_VER ) + #define _CRT_SECURE_NO_WARNINGS // This test file is not intended to be secure. +#endif +#include "tinyxml2.h" #include #include #include @@ -975,6 +978,15 @@ int main( int /*argc*/, const char ** /*argv*/ ) } #endif + { + // An assert should not fire. + const char* xml = ""; + XMLDocument doc; + doc.Parse( xml ); + XMLElement* ele = doc.NewElement( "unused" ); // This will get cleaned up with the 'doc' going out of scope. + XMLTest( "Tracking unused elements", true, ele != 0, false ); + } + // ----------- Performance tracking -------------- { #if defined( _MSC_VER )