2

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;
    }
}
18
  • You are missing a ; in the second for Commented Apr 22, 2014 at 8:18
  • 2
    Seems the professor made a good choice, as it's apparently not trivial to create a working implementation ;) Commented Apr 22, 2014 at 8:19
  • 2
    shouldnt the T(); be new T() ? Commented Apr 22, 2014 at 8:20
  • 1
    @user3559437 Can we see the constructor that was used for the object in question? Commented Apr 22, 2014 at 8:30
  • 1
    Actually, not setting used = size fixed the problem. Thank you, Veritas! Commented Apr 22, 2014 at 9:18

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.