From 6a567f3c772a12373d6ff85b929db039b947aac8 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 26 Oct 2007 01:03:23 +0000 Subject: [PATCH] fixed a memory corruption bug in CVector --- amxmodx/CVector.h | 30 ++++++--- dlls/engine/sdk/CVector.h | 129 +++++++++++++++++++++++++----------- dlls/fakemeta/sdk/CVector.h | 30 ++++++--- dlls/hamsandwich/CVector.h | 30 ++++++--- dlls/mysqlx/sdk/CVector.h | 30 ++++++--- dlls/ns/CVector.h | 30 ++++++--- dlls/ns/msvc7/ns.sln | 19 +++++- dlls/nvault/sdk/CVector.h | 129 +++++++++++++++++++++++++----------- dlls/regex/sdk/CVector.h | 129 +++++++++++++++++++++++++----------- dlls/sqlite/sdk/CVector.h | 30 ++++++--- 10 files changed, 420 insertions(+), 166 deletions(-) diff --git a/amxmodx/CVector.h b/amxmodx/CVector.h index 45f0d548..a6dc0048 100755 --- a/amxmodx/CVector.h +++ b/amxmodx/CVector.h @@ -37,12 +37,20 @@ // Vector template class CVector { - bool Grow() + bool Grow(size_t amount) { // automatic grow size_t newSize = m_Size * 2; + if (newSize == 0) - newSize = 8; // a good init value + { + newSize = 8; + } + + while (m_CurrentUsedSize + amount > newSize) + { + newSize *= 2; + } T *newData = new T[newSize]; if (!newData) return false; @@ -57,12 +65,16 @@ template class CVector return true; } - bool GrowIfNeeded() + bool GrowIfNeeded(size_t amount) { - if (m_CurrentUsedSize >= m_Size) - return Grow(); + if (m_CurrentUsedSize + amount >= m_Size) + { + return Grow(amount); + } else + { return true; + } } bool ChangeSize(size_t size) @@ -330,7 +342,7 @@ public: bool push_back(const T & elem) { ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + if (!GrowIfNeeded(1)) { --m_CurrentUsedSize; return false; @@ -434,13 +446,13 @@ public: size_t ofs = where - begin(); - ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + if (!GrowIfNeeded(1)) { - --m_CurrentUsedSize; return false; } + ++m_CurrentUsedSize; + where = begin() + ofs; // Move subsequent entries diff --git a/dlls/engine/sdk/CVector.h b/dlls/engine/sdk/CVector.h index d6b87eb5..a6dc0048 100755 --- a/dlls/engine/sdk/CVector.h +++ b/dlls/engine/sdk/CVector.h @@ -37,12 +37,20 @@ // Vector template class CVector { - bool Grow() + bool Grow(size_t amount) { // automatic grow size_t newSize = m_Size * 2; + if (newSize == 0) - newSize = 8; // a good init value + { + newSize = 8; + } + + while (m_CurrentUsedSize + amount > newSize) + { + newSize *= 2; + } T *newData = new T[newSize]; if (!newData) return false; @@ -57,12 +65,16 @@ template class CVector return true; } - bool GrowIfNeeded() + bool GrowIfNeeded(size_t amount) { - if (m_CurrentUsedSize >= m_Size) - return Grow(); + if (m_CurrentUsedSize + amount >= m_Size) + { + return Grow(amount); + } else + { return true; + } } bool ChangeSize(size_t size) @@ -70,32 +82,58 @@ template class CVector // change size if (size == m_Size) return true; + + if (!size) + { + if (m_Data) + { + delete [] m_Data; + m_Data = NULL; + m_Size = 0; + } + return true; + } + T *newData = new T[size]; if (!newData) return false; if (m_Data) { - size_t end = (m_Size < size) ? (m_Size) : size; + size_t end = (m_CurrentUsedSize < size) ? (m_CurrentUsedSize) : size; for (size_t i=0; i m_Size) + m_CurrentUsedSize = m_Size; + return true; } void FreeMemIfPossible() { + if (!m_Data) + return; + if (!m_CurrentUsedSize) + { + ChangeSize(0); + return; + } + + size_t newSize = m_Size; + while (m_CurrentUsedSize <= newSize / 2) + newSize /= 2; + + if (newSize != m_Size) + ChangeSize(newSize); } protected: T *m_Data; size_t m_Size; size_t m_CurrentUsedSize; - size_t m_CurrentSize; public: class iterator { @@ -189,7 +227,7 @@ public: iterator & operator-=(size_t offset) { - m_Ptr += offset; + m_Ptr -= offset; return (*this); } @@ -203,10 +241,10 @@ public: iterator operator-(size_t offset) const { iterator tmp(*this); - tmp.m_Ptr += offset; + tmp.m_Ptr -= offset; return tmp; } - + T & operator[](size_t offset) { return (*(*this + offset)); @@ -277,12 +315,12 @@ public: return m_Size; } - iterator begin() + iterator begin() const { return iterator(m_Data); } - iterator end() + iterator end() const { return iterator(m_Data + m_CurrentUsedSize); } @@ -296,13 +334,15 @@ public: bool reserve(size_t newSize) { - return ChangeSize(newSize); + if (newSize > m_Size) + return ChangeSize(newSize); + return true; } bool push_back(const T & elem) { ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + if (!GrowIfNeeded(1)) { --m_CurrentUsedSize; return false; @@ -317,14 +357,15 @@ public: --m_CurrentUsedSize; if (m_CurrentUsedSize < 0) m_CurrentUsedSize = 0; - // :TODO: free memory sometimes + + FreeMemIfPossible(); } bool resize(size_t newSize) { if (!ChangeSize(newSize)) return false; - FreeMemIfPossible(); + m_CurrentUsedSize = newSize; return true; } @@ -397,50 +438,64 @@ public: return m_Data[m_CurrentUsedSize - 1]; } - bool insert(iterator where, const T & value) + iterator insert(iterator where, const T & value) { - // we have to insert before - // if it is begin, don't decrement - if (where != m_Data) - --where; // validate iter - if (where < m_Data || where >= (m_Data + m_CurrentUsedSize)) - return false; + if (where < m_Data || where > (m_Data + m_CurrentUsedSize)) + return iterator(0); - ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + size_t ofs = where - begin(); + + if (!GrowIfNeeded(1)) { - --m_CurrentUsedSize; return false; } - memmove(where.base() + 1, where.base(), m_CurrentUsedSize - (where - m_Data)); - memcpy(where.base(), &value, sizeof(T)); - return true; + ++m_CurrentUsedSize; + + where = begin() + ofs; + + // Move subsequent entries + for (T *ptr = m_Data + m_CurrentUsedSize - 2; ptr >= where.base(); --ptr) + *(ptr + 1) = *ptr; + + *where.base() = value; + + return where; } - void erase(iterator where) + iterator erase(iterator where) { // validate iter if (where < m_Data || where >= (m_Data + m_CurrentUsedSize)) - return false; + return iterator(0); + + size_t ofs = where - begin(); if (m_CurrentUsedSize > 1) { // move - memmove(where.base(), where.base() + 1, m_CurrentUsedSize - 1); + T *theend = m_Data + m_CurrentUsedSize; + for (T *ptr = where.base() + 1; ptr < theend; ++ptr) + *(ptr - 1) = *ptr; } --m_CurrentUsedSize; - // :TODO: free memory sometimes + + FreeMemIfPossible(); + + return begin() + ofs; } void clear() { m_Size = 0; m_CurrentUsedSize = 0; - delete [] m_Data; - m_Data = NULL; + if (m_Data) + { + delete [] m_Data; + m_Data = NULL; + } } }; diff --git a/dlls/fakemeta/sdk/CVector.h b/dlls/fakemeta/sdk/CVector.h index 45f0d548..a6dc0048 100755 --- a/dlls/fakemeta/sdk/CVector.h +++ b/dlls/fakemeta/sdk/CVector.h @@ -37,12 +37,20 @@ // Vector template class CVector { - bool Grow() + bool Grow(size_t amount) { // automatic grow size_t newSize = m_Size * 2; + if (newSize == 0) - newSize = 8; // a good init value + { + newSize = 8; + } + + while (m_CurrentUsedSize + amount > newSize) + { + newSize *= 2; + } T *newData = new T[newSize]; if (!newData) return false; @@ -57,12 +65,16 @@ template class CVector return true; } - bool GrowIfNeeded() + bool GrowIfNeeded(size_t amount) { - if (m_CurrentUsedSize >= m_Size) - return Grow(); + if (m_CurrentUsedSize + amount >= m_Size) + { + return Grow(amount); + } else + { return true; + } } bool ChangeSize(size_t size) @@ -330,7 +342,7 @@ public: bool push_back(const T & elem) { ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + if (!GrowIfNeeded(1)) { --m_CurrentUsedSize; return false; @@ -434,13 +446,13 @@ public: size_t ofs = where - begin(); - ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + if (!GrowIfNeeded(1)) { - --m_CurrentUsedSize; return false; } + ++m_CurrentUsedSize; + where = begin() + ofs; // Move subsequent entries diff --git a/dlls/hamsandwich/CVector.h b/dlls/hamsandwich/CVector.h index d0fef2be..44f1f9dd 100644 --- a/dlls/hamsandwich/CVector.h +++ b/dlls/hamsandwich/CVector.h @@ -37,12 +37,20 @@ // Vector template class CVector { - bool Grow() + bool Grow(size_t amount) { // automatic grow size_t newSize = m_Size * 2; + if (newSize == 0) - newSize = 8; // a good init value + { + newSize = 8; + } + + while (m_CurrentUsedSize + amount > newSize) + { + newSize *= 2; + } T *newData = new T[newSize]; if (!newData) return false; @@ -57,12 +65,16 @@ template class CVector return true; } - bool GrowIfNeeded() + bool GrowIfNeeded(size_t amount) { - if (m_CurrentUsedSize >= m_Size) - return Grow(); + if (m_CurrentUsedSize + amount >= m_Size) + { + return Grow(amount); + } else + { return true; + } } bool ChangeSize(size_t size) @@ -330,7 +342,7 @@ public: bool push_back(const T & elem) { ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + if (!GrowIfNeeded(1)) { --m_CurrentUsedSize; return false; @@ -434,13 +446,13 @@ public: size_t ofs = where - begin(); - ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + if (!GrowIfNeeded(1)) { - --m_CurrentUsedSize; return false; } + ++m_CurrentUsedSize; + where = begin() + ofs; // Move subsequent entries diff --git a/dlls/mysqlx/sdk/CVector.h b/dlls/mysqlx/sdk/CVector.h index 45f0d548..a6dc0048 100755 --- a/dlls/mysqlx/sdk/CVector.h +++ b/dlls/mysqlx/sdk/CVector.h @@ -37,12 +37,20 @@ // Vector template class CVector { - bool Grow() + bool Grow(size_t amount) { // automatic grow size_t newSize = m_Size * 2; + if (newSize == 0) - newSize = 8; // a good init value + { + newSize = 8; + } + + while (m_CurrentUsedSize + amount > newSize) + { + newSize *= 2; + } T *newData = new T[newSize]; if (!newData) return false; @@ -57,12 +65,16 @@ template class CVector return true; } - bool GrowIfNeeded() + bool GrowIfNeeded(size_t amount) { - if (m_CurrentUsedSize >= m_Size) - return Grow(); + if (m_CurrentUsedSize + amount >= m_Size) + { + return Grow(amount); + } else + { return true; + } } bool ChangeSize(size_t size) @@ -330,7 +342,7 @@ public: bool push_back(const T & elem) { ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + if (!GrowIfNeeded(1)) { --m_CurrentUsedSize; return false; @@ -434,13 +446,13 @@ public: size_t ofs = where - begin(); - ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + if (!GrowIfNeeded(1)) { - --m_CurrentUsedSize; return false; } + ++m_CurrentUsedSize; + where = begin() + ofs; // Move subsequent entries diff --git a/dlls/ns/CVector.h b/dlls/ns/CVector.h index d0fef2be..44f1f9dd 100644 --- a/dlls/ns/CVector.h +++ b/dlls/ns/CVector.h @@ -37,12 +37,20 @@ // Vector template class CVector { - bool Grow() + bool Grow(size_t amount) { // automatic grow size_t newSize = m_Size * 2; + if (newSize == 0) - newSize = 8; // a good init value + { + newSize = 8; + } + + while (m_CurrentUsedSize + amount > newSize) + { + newSize *= 2; + } T *newData = new T[newSize]; if (!newData) return false; @@ -57,12 +65,16 @@ template class CVector return true; } - bool GrowIfNeeded() + bool GrowIfNeeded(size_t amount) { - if (m_CurrentUsedSize >= m_Size) - return Grow(); + if (m_CurrentUsedSize + amount >= m_Size) + { + return Grow(amount); + } else + { return true; + } } bool ChangeSize(size_t size) @@ -330,7 +342,7 @@ public: bool push_back(const T & elem) { ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + if (!GrowIfNeeded(1)) { --m_CurrentUsedSize; return false; @@ -434,13 +446,13 @@ public: size_t ofs = where - begin(); - ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + if (!GrowIfNeeded(1)) { - --m_CurrentUsedSize; return false; } + ++m_CurrentUsedSize; + where = begin() + ofs; // Move subsequent entries diff --git a/dlls/ns/msvc7/ns.sln b/dlls/ns/msvc7/ns.sln index d5074c4a..d75f5e7e 100755 --- a/dlls/ns/msvc7/ns.sln +++ b/dlls/ns/msvc7/ns.sln @@ -1,9 +1,26 @@  Microsoft Visual Studio Solution File, Format Version 8.00 -# Visual C++ Express 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ns", "ns.vcproj", "{5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}.Debug.ActiveCfg = Debug|Win32 + {5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}.Debug.Build.0 = Debug|Win32 + {5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}.Release.ActiveCfg = Release|Win32 + {5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 diff --git a/dlls/nvault/sdk/CVector.h b/dlls/nvault/sdk/CVector.h index d6b87eb5..a6dc0048 100755 --- a/dlls/nvault/sdk/CVector.h +++ b/dlls/nvault/sdk/CVector.h @@ -37,12 +37,20 @@ // Vector template class CVector { - bool Grow() + bool Grow(size_t amount) { // automatic grow size_t newSize = m_Size * 2; + if (newSize == 0) - newSize = 8; // a good init value + { + newSize = 8; + } + + while (m_CurrentUsedSize + amount > newSize) + { + newSize *= 2; + } T *newData = new T[newSize]; if (!newData) return false; @@ -57,12 +65,16 @@ template class CVector return true; } - bool GrowIfNeeded() + bool GrowIfNeeded(size_t amount) { - if (m_CurrentUsedSize >= m_Size) - return Grow(); + if (m_CurrentUsedSize + amount >= m_Size) + { + return Grow(amount); + } else + { return true; + } } bool ChangeSize(size_t size) @@ -70,32 +82,58 @@ template class CVector // change size if (size == m_Size) return true; + + if (!size) + { + if (m_Data) + { + delete [] m_Data; + m_Data = NULL; + m_Size = 0; + } + return true; + } + T *newData = new T[size]; if (!newData) return false; if (m_Data) { - size_t end = (m_Size < size) ? (m_Size) : size; + size_t end = (m_CurrentUsedSize < size) ? (m_CurrentUsedSize) : size; for (size_t i=0; i m_Size) + m_CurrentUsedSize = m_Size; + return true; } void FreeMemIfPossible() { + if (!m_Data) + return; + if (!m_CurrentUsedSize) + { + ChangeSize(0); + return; + } + + size_t newSize = m_Size; + while (m_CurrentUsedSize <= newSize / 2) + newSize /= 2; + + if (newSize != m_Size) + ChangeSize(newSize); } protected: T *m_Data; size_t m_Size; size_t m_CurrentUsedSize; - size_t m_CurrentSize; public: class iterator { @@ -189,7 +227,7 @@ public: iterator & operator-=(size_t offset) { - m_Ptr += offset; + m_Ptr -= offset; return (*this); } @@ -203,10 +241,10 @@ public: iterator operator-(size_t offset) const { iterator tmp(*this); - tmp.m_Ptr += offset; + tmp.m_Ptr -= offset; return tmp; } - + T & operator[](size_t offset) { return (*(*this + offset)); @@ -277,12 +315,12 @@ public: return m_Size; } - iterator begin() + iterator begin() const { return iterator(m_Data); } - iterator end() + iterator end() const { return iterator(m_Data + m_CurrentUsedSize); } @@ -296,13 +334,15 @@ public: bool reserve(size_t newSize) { - return ChangeSize(newSize); + if (newSize > m_Size) + return ChangeSize(newSize); + return true; } bool push_back(const T & elem) { ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + if (!GrowIfNeeded(1)) { --m_CurrentUsedSize; return false; @@ -317,14 +357,15 @@ public: --m_CurrentUsedSize; if (m_CurrentUsedSize < 0) m_CurrentUsedSize = 0; - // :TODO: free memory sometimes + + FreeMemIfPossible(); } bool resize(size_t newSize) { if (!ChangeSize(newSize)) return false; - FreeMemIfPossible(); + m_CurrentUsedSize = newSize; return true; } @@ -397,50 +438,64 @@ public: return m_Data[m_CurrentUsedSize - 1]; } - bool insert(iterator where, const T & value) + iterator insert(iterator where, const T & value) { - // we have to insert before - // if it is begin, don't decrement - if (where != m_Data) - --where; // validate iter - if (where < m_Data || where >= (m_Data + m_CurrentUsedSize)) - return false; + if (where < m_Data || where > (m_Data + m_CurrentUsedSize)) + return iterator(0); - ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + size_t ofs = where - begin(); + + if (!GrowIfNeeded(1)) { - --m_CurrentUsedSize; return false; } - memmove(where.base() + 1, where.base(), m_CurrentUsedSize - (where - m_Data)); - memcpy(where.base(), &value, sizeof(T)); - return true; + ++m_CurrentUsedSize; + + where = begin() + ofs; + + // Move subsequent entries + for (T *ptr = m_Data + m_CurrentUsedSize - 2; ptr >= where.base(); --ptr) + *(ptr + 1) = *ptr; + + *where.base() = value; + + return where; } - void erase(iterator where) + iterator erase(iterator where) { // validate iter if (where < m_Data || where >= (m_Data + m_CurrentUsedSize)) - return false; + return iterator(0); + + size_t ofs = where - begin(); if (m_CurrentUsedSize > 1) { // move - memmove(where.base(), where.base() + 1, m_CurrentUsedSize - 1); + T *theend = m_Data + m_CurrentUsedSize; + for (T *ptr = where.base() + 1; ptr < theend; ++ptr) + *(ptr - 1) = *ptr; } --m_CurrentUsedSize; - // :TODO: free memory sometimes + + FreeMemIfPossible(); + + return begin() + ofs; } void clear() { m_Size = 0; m_CurrentUsedSize = 0; - delete [] m_Data; - m_Data = NULL; + if (m_Data) + { + delete [] m_Data; + m_Data = NULL; + } } }; diff --git a/dlls/regex/sdk/CVector.h b/dlls/regex/sdk/CVector.h index d6b87eb5..a6dc0048 100755 --- a/dlls/regex/sdk/CVector.h +++ b/dlls/regex/sdk/CVector.h @@ -37,12 +37,20 @@ // Vector template class CVector { - bool Grow() + bool Grow(size_t amount) { // automatic grow size_t newSize = m_Size * 2; + if (newSize == 0) - newSize = 8; // a good init value + { + newSize = 8; + } + + while (m_CurrentUsedSize + amount > newSize) + { + newSize *= 2; + } T *newData = new T[newSize]; if (!newData) return false; @@ -57,12 +65,16 @@ template class CVector return true; } - bool GrowIfNeeded() + bool GrowIfNeeded(size_t amount) { - if (m_CurrentUsedSize >= m_Size) - return Grow(); + if (m_CurrentUsedSize + amount >= m_Size) + { + return Grow(amount); + } else + { return true; + } } bool ChangeSize(size_t size) @@ -70,32 +82,58 @@ template class CVector // change size if (size == m_Size) return true; + + if (!size) + { + if (m_Data) + { + delete [] m_Data; + m_Data = NULL; + m_Size = 0; + } + return true; + } + T *newData = new T[size]; if (!newData) return false; if (m_Data) { - size_t end = (m_Size < size) ? (m_Size) : size; + size_t end = (m_CurrentUsedSize < size) ? (m_CurrentUsedSize) : size; for (size_t i=0; i m_Size) + m_CurrentUsedSize = m_Size; + return true; } void FreeMemIfPossible() { + if (!m_Data) + return; + if (!m_CurrentUsedSize) + { + ChangeSize(0); + return; + } + + size_t newSize = m_Size; + while (m_CurrentUsedSize <= newSize / 2) + newSize /= 2; + + if (newSize != m_Size) + ChangeSize(newSize); } protected: T *m_Data; size_t m_Size; size_t m_CurrentUsedSize; - size_t m_CurrentSize; public: class iterator { @@ -189,7 +227,7 @@ public: iterator & operator-=(size_t offset) { - m_Ptr += offset; + m_Ptr -= offset; return (*this); } @@ -203,10 +241,10 @@ public: iterator operator-(size_t offset) const { iterator tmp(*this); - tmp.m_Ptr += offset; + tmp.m_Ptr -= offset; return tmp; } - + T & operator[](size_t offset) { return (*(*this + offset)); @@ -277,12 +315,12 @@ public: return m_Size; } - iterator begin() + iterator begin() const { return iterator(m_Data); } - iterator end() + iterator end() const { return iterator(m_Data + m_CurrentUsedSize); } @@ -296,13 +334,15 @@ public: bool reserve(size_t newSize) { - return ChangeSize(newSize); + if (newSize > m_Size) + return ChangeSize(newSize); + return true; } bool push_back(const T & elem) { ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + if (!GrowIfNeeded(1)) { --m_CurrentUsedSize; return false; @@ -317,14 +357,15 @@ public: --m_CurrentUsedSize; if (m_CurrentUsedSize < 0) m_CurrentUsedSize = 0; - // :TODO: free memory sometimes + + FreeMemIfPossible(); } bool resize(size_t newSize) { if (!ChangeSize(newSize)) return false; - FreeMemIfPossible(); + m_CurrentUsedSize = newSize; return true; } @@ -397,50 +438,64 @@ public: return m_Data[m_CurrentUsedSize - 1]; } - bool insert(iterator where, const T & value) + iterator insert(iterator where, const T & value) { - // we have to insert before - // if it is begin, don't decrement - if (where != m_Data) - --where; // validate iter - if (where < m_Data || where >= (m_Data + m_CurrentUsedSize)) - return false; + if (where < m_Data || where > (m_Data + m_CurrentUsedSize)) + return iterator(0); - ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + size_t ofs = where - begin(); + + if (!GrowIfNeeded(1)) { - --m_CurrentUsedSize; return false; } - memmove(where.base() + 1, where.base(), m_CurrentUsedSize - (where - m_Data)); - memcpy(where.base(), &value, sizeof(T)); - return true; + ++m_CurrentUsedSize; + + where = begin() + ofs; + + // Move subsequent entries + for (T *ptr = m_Data + m_CurrentUsedSize - 2; ptr >= where.base(); --ptr) + *(ptr + 1) = *ptr; + + *where.base() = value; + + return where; } - void erase(iterator where) + iterator erase(iterator where) { // validate iter if (where < m_Data || where >= (m_Data + m_CurrentUsedSize)) - return false; + return iterator(0); + + size_t ofs = where - begin(); if (m_CurrentUsedSize > 1) { // move - memmove(where.base(), where.base() + 1, m_CurrentUsedSize - 1); + T *theend = m_Data + m_CurrentUsedSize; + for (T *ptr = where.base() + 1; ptr < theend; ++ptr) + *(ptr - 1) = *ptr; } --m_CurrentUsedSize; - // :TODO: free memory sometimes + + FreeMemIfPossible(); + + return begin() + ofs; } void clear() { m_Size = 0; m_CurrentUsedSize = 0; - delete [] m_Data; - m_Data = NULL; + if (m_Data) + { + delete [] m_Data; + m_Data = NULL; + } } }; diff --git a/dlls/sqlite/sdk/CVector.h b/dlls/sqlite/sdk/CVector.h index 45f0d548..a6dc0048 100755 --- a/dlls/sqlite/sdk/CVector.h +++ b/dlls/sqlite/sdk/CVector.h @@ -37,12 +37,20 @@ // Vector template class CVector { - bool Grow() + bool Grow(size_t amount) { // automatic grow size_t newSize = m_Size * 2; + if (newSize == 0) - newSize = 8; // a good init value + { + newSize = 8; + } + + while (m_CurrentUsedSize + amount > newSize) + { + newSize *= 2; + } T *newData = new T[newSize]; if (!newData) return false; @@ -57,12 +65,16 @@ template class CVector return true; } - bool GrowIfNeeded() + bool GrowIfNeeded(size_t amount) { - if (m_CurrentUsedSize >= m_Size) - return Grow(); + if (m_CurrentUsedSize + amount >= m_Size) + { + return Grow(amount); + } else + { return true; + } } bool ChangeSize(size_t size) @@ -330,7 +342,7 @@ public: bool push_back(const T & elem) { ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + if (!GrowIfNeeded(1)) { --m_CurrentUsedSize; return false; @@ -434,13 +446,13 @@ public: size_t ofs = where - begin(); - ++m_CurrentUsedSize; - if (!GrowIfNeeded()) + if (!GrowIfNeeded(1)) { - --m_CurrentUsedSize; return false; } + ++m_CurrentUsedSize; + where = begin() + ofs; // Move subsequent entries