Fix illegal memory access on push_front, and merge push methods into one base function.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2825 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2009-11-10 09:51:13 +00:00
parent 007094898f
commit e2b8f785ca
1 changed files with 60 additions and 57 deletions

View File

@ -30,6 +30,7 @@ public:
{
}
//! Constructs an array and allocates an initial chunk of memory.
/** \param start_count Amount of elements to pre-allocate. */
array(u32 start_count)
@ -48,7 +49,6 @@ public:
}
//! Destructor.
/** Frees allocated memory, if set_free_when_destroyed was not set to
false by the user before. */
@ -102,48 +102,13 @@ public:
strategy = newStrategy;
}
//! Adds an element at back of array.
/** If the array is too small to add this new element it is made bigger.
\param element: Element to add at the back of the array. */
void push_back(const T& element)
{
if (used + 1 > allocated)
{
// this doesn't work if the element is in the same array. So
// we'll copy the element first to be sure we'll get no data
// corruption
T e(element);
//reallocate(used * 2 +1); // increase data block
// TA: okt, 2008. it's only allowed to alloc one element, if
// default constructor has to be called
// increase data block
u32 newAlloc;
switch ( strategy )
{
case ALLOC_STRATEGY_DOUBLE:
newAlloc = used + 1 + (allocated < 500 ?
(allocated < 5 ? 5 : used) : used >> 2);
break;
default:
case ALLOC_STRATEGY_SAFE:
newAlloc = used + 1;
break;
}
reallocate( newAlloc);
// construct new element
// Attention!. in missing default constructors for faster alloc methods
allocator.construct(&data[used++], e); // data[used++] = e; // push_back
}
else
{
//data[used++] = element;
// instead of using this here, we copy it the safe way:
allocator.construct(&data[used++], element);
}
is_sorted = false;
insert(element, used);
}
@ -169,18 +134,55 @@ public:
_IRR_DEBUG_BREAK_IF(index>used) // access violation
if (used + 1 > allocated)
reallocate(used +1);
for (u32 i=used; i>index; --i)
{
if (i<used)
allocator.destruct(&data[i]);
allocator.construct(&data[i], data[i-1]); // data[i] = data[i-1];
}
// this doesn't work if the element is in the same
// array. So we'll copy the element first to be sure
// we'll get no data corruption
const T e(element);
if (used > index)
allocator.destruct(&data[index]);
allocator.construct(&data[index], element); // data[index] = element;
//reallocate(used * 2 +1); // increase data block
// TA: okt, 2008. it's only allowed to alloc one element, if
// default constructor has to be called
// increase data block
u32 newAlloc;
switch ( strategy )
{
case ALLOC_STRATEGY_DOUBLE:
newAlloc = used + 1 + (allocated < 500 ?
(allocated < 5 ? 5 : used) : used >> 2);
break;
default:
case ALLOC_STRATEGY_SAFE:
newAlloc = used + 1;
break;
}
reallocate( newAlloc);
// construct new element
for (u32 i=used; i>index; --i)
{
if (i<used)
allocator.destruct(&data[i]);
allocator.construct(&data[i], data[i-1]); // data[i] = data[i-1];
}
if (used > index)
allocator.destruct(&data[index]);
allocator.construct(&data[index], e); // data[index] = e;
}
else
{
for (u32 i=used; i>index; --i)
{
if (i<used)
allocator.destruct(&data[i]);
allocator.construct(&data[i], data[i-1]); // data[i] = data[i-1];
}
if (used > index)
allocator.destruct(&data[index]);
allocator.construct(&data[index], element); // data[index] = element;
}
is_sorted = false;
++used;
}
@ -279,6 +281,7 @@ public:
return true;
}
//! Inequality operator
bool operator != (const array<T>& other) const
{
@ -473,6 +476,7 @@ public:
return index;
}
//! Finds an element in linear time, which is very slow.
/** Use binary_search for faster finding. Only works if ==operator is
implemented.
@ -559,21 +563,20 @@ public:
is_sorted = _is_sorted;
}
private:
T* data;
u32 allocated;
u32 used;
TAlloc allocator;
eAllocStrategy strategy:4;
bool free_when_destroyed:1;
bool is_sorted:1;
private:
T* data;
u32 allocated;
u32 used;
TAlloc allocator;
eAllocStrategy strategy:4;
bool free_when_destroyed:1;
bool is_sorted:1;
};
} // end namespace core
} // end namespace irr
#endif