Question

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;
    }
}
Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top