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