动态数组调整大小函数问题

Dynamic array resize function problems

本文关键字:函数 问题 数组 调整 动态      更新时间:2023-10-16

注意:我知道只使用STL Vector会更容易,但是,对于我所在的编程类,我们需要编写自己的动态数组模板类,因为我们的教授显然喜欢让我们重新发明轮子。

无论如何,我为我的动态数组模板类制作了一个调整大小的函数,如下所示。注意,私有成员变量是T*arr、unsigned used和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;
    }
}

每当我使用这个函数来增加数组的大小时,它都会在我第一次需要使用它时工作,但在那之后,Visual Studio会在第14行触发一个断点(delete[] arr),如果我继续超过这个断点,我最终会得到_CrtIsValidHeapPointer(pUserData)断言失败。造成这种情况的原因是什么?我该如何解决?

构造函数:

template <class T>
darray<T>::darray()
{
used = 0;
cap = 64;
arr = new T[cap];
for (int count = 0; count < cap; ++count)
    arr[count] = T();

}

分配运算符:

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;
}

析构函数:

template <class T>
darray<T>::~darray()
{
    delete[] arr;
}

有人要求使用push_back函数,所以下面也是:

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;
    }
}

您的resize函数会增加used。在push_back中访问arr[used+1]时,访问的数组位置无效。

您应该添加另一个函数,它类似于resize,但只更改数组的容量,而不更改存储的对象计数。(即它不递增used)。此函数应由push_back调用。(正如您在问题中提到的std::vector,请参阅vector::resize和vector::reserve之间的区别。)

另外:数组索引是从零开始的。不要在used + 1位置插入,而是在used位置插入。

我将使用下一个实现。我假设"cap"成员表示向量的容量,"used"表示数组中元素的数量。

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;
}

优点:每次使用大量元素调整大小时,不需要重新分配整个数组。

缺点:当你不需要的时候,你会花额外的空间。