我正在尝试实现一个具有动态长度的自制矢量类。这个想法是使用指针和动态分配的空间,如下所示。
template<class T>
class myVector
{
int size;
T* array;
public:
myVector(int n): size(n), array(new T[n]){}
~myVector(){delete[] array;}
T pop();
...
}
如果需要推送,则创建一个带有新指针的新对象,该指针指向新分配的空间并复制整个对象。现在,我被卡在了pop上,因为我不知道在调用pop()之后如何释放未使用的空间。
这样在pop()中使用delete可以吗
T pop()
{
T = *(array+size-1);
delete array+size-1;
return T;
}
但是,如果我这样做,那么在调用析构函数时,弹出的位置将被删除两次,我认为这可能会出错。而且我知道我可以等到整个数组为空后再删除,但是可能会发生,首先分配了一个很大的数组,并且在程序运行时弹出了很多数组,如果我这样做,可能会导致大量未使用的空间不要在中间释放它们。
我的问题:
(1)如果我在pop()中写入delete会怎样?
(2)我该怎么办? (最好仅使用delele)
答案 0 :(得分:5)
您的代码存在严重缺陷。
首先,必须用new T[N]
删除任何delete[]
。因此,您的析构函数需要使用delete[]
,而不是delete
。
然后,您不能使用delete
从缓冲区中弹出单个元素。这是未定义的行为(安全风险),因为尚未为元素分配new
。
实际向量处理此问题的方法是在堆上分配char
的缓冲区,然后使用 placement在缓冲区中手动调用T
的构造函数和析构函数new
和显式析构函数调用。
答案 1 :(得分:1)
您必须delete
new
,delete[]
new[]
,什么都不要。您不能从动态分配的数组中删除单个元素,而只能删除整个东西。您当前的析构函数具有不确定的行为,因为您delete
使用new[]
创建了某些东西。
1)发生未定义的行为。不要这样做。
2)删除整个数组,并分配一个少一个的新数组。既然这对性能很不利(添加N
元素具有O(N^2)
运行时),那么您应该研究一下std::vector
的大小和容量。