Преглед на файлове

fix incorrect assert on unused memory

Lee Thomason преди 13 години
родител
ревизия
5b0a677712
променени са 4 файла, в които са добавени 50 реда и са изтрити 23 реда
  1. 14 4
      tinyxml2.cpp
  2. 16 5
      tinyxml2.h
  3. 7 13
      tinyxml2.sln
  4. 13 1
      xmltest.cpp

+ 14 - 4
tinyxml2.cpp

@@ -669,6 +669,7 @@ XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )
         addThis->_next = 0;
         addThis->_next = 0;
     }
     }
     addThis->_parent = this;
     addThis->_parent = this;
+    addThis->_memPool->SetTracked();
     return addThis;
     return addThis;
 }
 }
 
 
@@ -693,6 +694,7 @@ XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis )
         addThis->_next = 0;
         addThis->_next = 0;
     }
     }
     addThis->_parent = this;
     addThis->_parent = this;
+    addThis->_memPool->SetTracked();
     return addThis;
     return addThis;
 }
 }
 
 
@@ -713,6 +715,7 @@ XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis )
     afterThis->_next->_prev = addThis;
     afterThis->_next->_prev = addThis;
     afterThis->_next = addThis;
     afterThis->_next = addThis;
     addThis->_parent = this;
     addThis->_parent = this;
+    addThis->_memPool->SetTracked();
     return addThis;
     return addThis;
 }
 }
 
 
@@ -814,6 +817,7 @@ char* XMLNode::ParseDeep( char* p, StrPair* parentEnd )
             if ( parentEnd ) {
             if ( parentEnd ) {
                 *parentEnd = static_cast<XMLElement*>(node)->_value;
                 *parentEnd = static_cast<XMLElement*>(node)->_value;
             }
             }
+			node->_memPool->SetTracked();	// created and then immediately deleted.
             DELETE_NODE( node );
             DELETE_NODE( node );
             return p;
             return p;
         }
         }
@@ -1314,6 +1318,7 @@ XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name )
             _rootAttribute = attrib;
             _rootAttribute = attrib;
         }
         }
         attrib->SetName( name );
         attrib->SetName( name );
+        attrib->_memPool->SetTracked(); // always created and linked.
     }
     }
     return attrib;
     return attrib;
 }
 }
@@ -1355,6 +1360,7 @@ char* XMLElement::ParseAttributes( char* p )
         if ( XMLUtil::IsAlpha( *p ) ) {
         if ( XMLUtil::IsAlpha( *p ) ) {
             XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute();
             XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute();
             attrib->_memPool = &_document->_attributePool;
             attrib->_memPool = &_document->_attributePool;
+			attrib->_memPool->SetTracked();
 
 
             p = attrib->ParseDeep( p, _document->ProcessEntities() );
             p = attrib->ParseDeep( p, _document->ProcessEntities() );
             if ( !p || Attribute( attrib->Name() ) ) {
             if ( !p || Attribute( attrib->Name() ) ) {
@@ -1508,10 +1514,14 @@ XMLDocument::~XMLDocument()
     attributePool.Trace( "attribute" );
     attributePool.Trace( "attribute" );
 #endif
 #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
 }
 }
 
 
 
 

+ 16 - 5
tinyxml2.h

@@ -45,7 +45,7 @@ distribution.
 */
 */
 /*
 /*
 	gcc:
 	gcc:
-        g++ -Wall tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
+        g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
     
     
     Formatting, Artistic Style:
     Formatting, Artistic Style:
         AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
         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
 #define TIXML_SSCANF   sscanf
 #endif
 #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
 namespace tinyxml2
 {
 {
@@ -285,6 +285,7 @@ public:
     virtual int ItemSize() const = 0;
     virtual int ItemSize() const = 0;
     virtual void* Alloc() = 0;
     virtual void* Alloc() = 0;
     virtual void Free( void* ) = 0;
     virtual void Free( void* ) = 0;
+    virtual void SetTracked() = 0;
 };
 };
 
 
 
 
@@ -295,7 +296,7 @@ template< int SIZE >
 class MemPoolT : public MemPool
 class MemPoolT : public MemPool
 {
 {
 public:
 public:
-    MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0)	{}
+    MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0)	{}
     ~MemPoolT() {
     ~MemPoolT() {
         // Delete the blocks.
         // Delete the blocks.
         for( int i=0; i<_blockPtrs.Size(); ++i ) {
         for( int i=0; i<_blockPtrs.Size(); ++i ) {
@@ -330,6 +331,7 @@ public:
             _maxAllocs = _currentAllocs;
             _maxAllocs = _currentAllocs;
         }
         }
         _nAllocs++;
         _nAllocs++;
+        _nUntracked++;
         return result;
         return result;
     }
     }
     virtual void Free( void* mem ) {
     virtual void Free( void* mem ) {
@@ -349,6 +351,14 @@ public:
                 name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() );
                 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
     enum { COUNT = 1024/SIZE }; // Some compilers do not accept to use COUNT in private part if COUNT is private
 
 
 private:
 private:
@@ -365,6 +375,7 @@ private:
     int _currentAllocs;
     int _currentAllocs;
     int _nAllocs;
     int _nAllocs;
     int _maxAllocs;
     int _maxAllocs;
+    int _nUntracked;
 };
 };
 
 
 
 

+ 7 - 13
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
 EndProject
 Global
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
 		Debug|Win32 = Debug|Win32
-		Debug|x64 = Debug|x64
 		Release|Win32 = Release|Win32
 		Release|Win32 = Release|Win32
-		Release|x64 = Release|x64
 	EndGlobalSection
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 	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
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 		HideSolutionNode = FALSE

+ 13 - 1
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 <cstdlib>
 #include <cstdlib>
 #include <cstring>
 #include <cstring>
 #include <ctime>
 #include <ctime>
@@ -975,6 +978,15 @@ int main( int /*argc*/, const char ** /*argv*/ )
 	}
 	}
 #endif
 #endif
 
 
+	{
+		// An assert should not fire.
+		const char* xml = "<element/>";
+		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 --------------
 	// ----------- Performance tracking --------------
 	{
 	{
 #if defined( _MSC_VER )
 #if defined( _MSC_VER )