Fix inserting an element of wxArrayString itself back into it.
Do the insertion/addition before deallocating the old memory to allow things like array.Add(array[0]) to work correctly. Closes #2290. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76909 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -364,7 +364,10 @@ protected:
|
|||||||
CompareFunction m_compareFunction; // set only from wxSortedArrayString
|
CompareFunction m_compareFunction; // set only from wxSortedArrayString
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Grow(size_t nIncrement = 0); // makes array bigger if needed
|
// Allocate the new buffer big enough to hold m_nCount + nIncrement items and
|
||||||
|
// return the pointer to the old buffer, which must be deleted by the caller
|
||||||
|
// (if the old buffer is big enough, just return NULL).
|
||||||
|
wxString *Grow(size_t nIncrement);
|
||||||
|
|
||||||
size_t m_nSize, // current size of the array
|
size_t m_nSize, // current size of the array
|
||||||
m_nCount; // current number of elements
|
m_nCount; // current number of elements
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/arrstr.h"
|
#include "wx/arrstr.h"
|
||||||
|
#include "wx/scopedarray.h"
|
||||||
|
|
||||||
#include "wx/beforestd.h"
|
#include "wx/beforestd.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -107,10 +108,14 @@ void wxArrayString::Copy(const wxArrayString& src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// grow the array
|
// grow the array
|
||||||
void wxArrayString::Grow(size_t nIncrement)
|
wxString *wxArrayString::Grow(size_t nIncrement)
|
||||||
{
|
{
|
||||||
// only do it if no more place
|
if ( (m_nSize - m_nCount) >= nIncrement )
|
||||||
if ( (m_nSize - m_nCount) < nIncrement ) {
|
{
|
||||||
|
// We already have enough space.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// if ARRAY_DEFAULT_INITIAL_SIZE were set to 0, the initially empty would
|
// if ARRAY_DEFAULT_INITIAL_SIZE were set to 0, the initially empty would
|
||||||
// be never resized!
|
// be never resized!
|
||||||
#if ARRAY_DEFAULT_INITIAL_SIZE == 0
|
#if ARRAY_DEFAULT_INITIAL_SIZE == 0
|
||||||
@@ -123,6 +128,9 @@ void wxArrayString::Grow(size_t nIncrement)
|
|||||||
if (m_nSize < nIncrement)
|
if (m_nSize < nIncrement)
|
||||||
m_nSize = nIncrement;
|
m_nSize = nIncrement;
|
||||||
m_pItems = new wxString[m_nSize];
|
m_pItems = new wxString[m_nSize];
|
||||||
|
|
||||||
|
// Nothing to free, we hadn't had any memory before.
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// otherwise when it's called for the first time, nIncrement would be 0
|
// otherwise when it's called for the first time, nIncrement would be 0
|
||||||
@@ -141,12 +149,12 @@ void wxArrayString::Grow(size_t nIncrement)
|
|||||||
for ( size_t j = 0; j < m_nCount; j++ )
|
for ( size_t j = 0; j < m_nCount; j++ )
|
||||||
pNew[j] = m_pItems[j];
|
pNew[j] = m_pItems[j];
|
||||||
|
|
||||||
// delete old memory (but do not release the strings!)
|
wxString* const pItemsOld = m_pItems;
|
||||||
delete [] m_pItems;
|
|
||||||
|
|
||||||
m_pItems = pNew;
|
m_pItems = pNew;
|
||||||
|
|
||||||
|
return pItemsOld;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// deletes all the strings from the list
|
// deletes all the strings from the list
|
||||||
@@ -289,7 +297,10 @@ size_t wxArrayString::Add(const wxString& str, size_t nInsert)
|
|||||||
return (size_t)lo;
|
return (size_t)lo;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Grow(nInsert);
|
// Now that we must postpone freeing the old memory until we don't need it
|
||||||
|
// any more, i.e. don't reference "str" which could be a reference to one
|
||||||
|
// of our own strings.
|
||||||
|
wxScopedArray<wxString> oldStrings(Grow(nInsert));
|
||||||
|
|
||||||
for (size_t i = 0; i < nInsert; i++)
|
for (size_t i = 0; i < nInsert; i++)
|
||||||
{
|
{
|
||||||
@@ -309,7 +320,7 @@ void wxArrayString::Insert(const wxString& str, size_t nIndex, size_t nInsert)
|
|||||||
wxCHECK_RET( m_nCount <= m_nCount + nInsert,
|
wxCHECK_RET( m_nCount <= m_nCount + nInsert,
|
||||||
wxT("array size overflow in wxArrayString::Insert") );
|
wxT("array size overflow in wxArrayString::Insert") );
|
||||||
|
|
||||||
Grow(nInsert);
|
wxScopedArray<wxString> oldStrings(Grow(nInsert));
|
||||||
|
|
||||||
for (int j = m_nCount - nIndex - 1; j >= 0; j--)
|
for (int j = m_nCount - nIndex - 1; j >= 0; j--)
|
||||||
m_pItems[nIndex + nInsert + j] = m_pItems[nIndex + j];
|
m_pItems[nIndex + nInsert + j] = m_pItems[nIndex + j];
|
||||||
@@ -328,7 +339,7 @@ wxArrayString::insert(iterator it, const_iterator first, const_iterator last)
|
|||||||
const int idx = it - begin();
|
const int idx = it - begin();
|
||||||
|
|
||||||
// grow it once
|
// grow it once
|
||||||
Grow(last - first);
|
wxScopedArray<wxString> oldStrings(Grow(last - first));
|
||||||
|
|
||||||
// reset "it" since it can change inside Grow()
|
// reset "it" since it can change inside Grow()
|
||||||
it = begin() + idx;
|
it = begin() + idx;
|
||||||
|
@@ -346,6 +346,10 @@ void ArraysTestCase::wxStringArrayTest()
|
|||||||
a5.resize(3);
|
a5.resize(3);
|
||||||
CPPUNIT_ASSERT_EQUAL( 3, a5.size() );
|
CPPUNIT_ASSERT_EQUAL( 3, a5.size() );
|
||||||
CPPUNIT_ASSERT_EQUAL( "Foo", a5[2] );
|
CPPUNIT_ASSERT_EQUAL( "Foo", a5[2] );
|
||||||
|
|
||||||
|
wxArrayString a6;
|
||||||
|
a6.Add("Foo");
|
||||||
|
a6.Insert(a6[0], 1, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArraysTestCase::SortedArray()
|
void ArraysTestCase::SortedArray()
|
||||||
|
Reference in New Issue
Block a user