注意:我知道使用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;
}
}
答案 0 :(得分:2)
resize
功能增加used
。当您访问arr[used+1]
中的push_back
时,访问无效的阵列位置。
您应该添加另一个类似于resize
的函数,但只更改数组的容量而不是存储的对象数。 (即它不会增加used
)。该函数应由push_back
调用。 (正如您在问题中提到的那样std::vector
,请参阅vector::resize和vector::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;
}
优点:每次使用大量元素调整大小时,都不需要重新分配整个数组。
缺点:当你不需要时,你会花费额外的空间。