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

时间:2014-04-22 08:14:06

标签: c++ arrays pointers delete-operator

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

无论如何,我为动态数组模板类创建了一个resize函数,如下所示。请注意,私有成员变量是T * arr,未签名使用和无符号上限。

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 Studios将在第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;
    }
}

2 个答案:

答案 0 :(得分:2)

resize功能增加used。当您访问arr[used+1]中的push_back时,访问无效的阵列位置。

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

另外:数组索引从零开始。请勿在{{1​​}}位置插入,而是在位置used + 1上插入。

答案 1 :(得分:0)

我会使用下一个实现。我认为&#34; cap&#34;成员是为了矢量和&#34;使用&#34;是数组中元素的数量。

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

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

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