Reputation: 71
NOTE: I am aware that it would be easier to just use the STL Vector, however, for a programming class that I'm in, we are required to write our own dynamic array template class because our professor apparently enjoys making us reinvent the wheel.
Anyway, I made a resize function for my dynamic array template class that goes as follows. Note that the private member variables are T* arr, unsigned used, and unsigned cap.
template <class T>
void darray<T>::resize(unsigned size)
{
if (size > cap)
{
T* temp_arr = new T[size];
for (int count = 0; count < used; ++count)
temp_arr[count] = arr[count];
for (int count = used; count < size; ++count)
temp_arr[count] = T();
delete []arr;
arr = temp_arr;
cap = size;
used = size;
}
if (size < cap)
{
used = size;
}
}
Whenever I use this function to increase the size of the array, it will work the first time I need to use it, but after that, Visual Studios will trigger a breakpoint at line 14 (delete[] arr
), and if I continue past the breaks, I eventually get _CrtIsValidHeapPointer(pUserData)
assertion failure. What is causing this, and how can I fix it?
constructor:
template <class T>
darray<T>::darray()
{
used = 0;
cap = 64;
arr = new T[cap];
for (int count = 0; count < cap; ++count)
arr[count] = T();
}
assignment operator:
template <class T>
darray<T>& darray<T>::operator= (const darray& right_operand)
{
delete[] arr;
arr = new T[right_operand.capacity()];
used = right_operand.size();
cap = right_operand.capacity();
for (int count = 0; count < used; ++count)
arr[count] = right_operand[count];
return *this;
}
destructor:
template <class T>
darray<T>::~darray()
{
delete[] arr;
}
There's been some requests for the push_back function, so here's that as well:
template <class T>
void darray<T>::push_back(const T& input)
{
if ((used + 1) > cap)
{
resize(cap * 2);
arr[used + 1] = input;
++used;
}
else
{
arr[used] = input;
++used;
}
}
Upvotes: 2
Views: 405
Reputation: 4247
Your resize
function increases used
. When you access arr[used+1]
in push_back
, than you access an invalid array location.
You should add another function, which is similar to resize
, but changes only the capacity of your array and not the stored object count. (i.e. it does not increment used
). This function should be called by push_back
. (As you mentioned std::vector
in your question, see the difference between vector::resize and vector::reserve.)
Also: array indexes are zero-based. Do not insert at position used + 1
but on position used
.
Upvotes: 2
Reputation: 683
I would use next implementation. I assume that "cap" member is for capacity of vector and "used" is for amount of elements in array.
template <class T>
void darray<T>::resize(unsigned size)
{
if (size > cap)
{
cap = size * 2;
T* temp_arr = new T[cap];
for (int count = 0; count < used; ++count)
temp_arr[count] = arr[count];
delete [] arr;
arr = temp_arr;
}
// zero members if size was decreased
if (size < used)
{
for (int count = size; count < used; ++count)
arr[count] = T();
}
used = size;
}
Pros: You don't need to reallocate the whole array each time you do a resize with larger number of elements.
Cons: You spend an extra space when you don't need to.
Upvotes: 0