好的,首先我编写了这个方法,事先搜索了stackoverflow,注意到了我的 想法与大多数人的做法相符,但是,堆栈实际上并没有被反转,而是将奇怪的值放入其中:
我这样做:我创建一个辅助堆栈和一个条件大小为!= 0的while循环,然后我调用aux.push(pop())因为pop方法也返回了被删除的元素,因此堆栈应该反转,并且在O(n)时间复杂度。但是,这种情况发生了:
要反击的堆叠:C D F - >结果:ĐĐ`
我跑了一个内存泄漏测试仪,它告诉我我有4次尝试释放已经释放的空间,所以我认为这可能是原因。
更多详情:
Stack实现为动态数组
以下是具有相关功能的代码:
template<typename T>
bool NizStek<T>::push(const T& element){
if(_size == _capacity) increaseCapacity();
if(_size == 0){
_brojE++;
_top++;
_array[_top] = new T(element);
}
else{
_size++;
++_top;
_array[_top] = new T(element);
}
}
POP功能:
template<typename T>
T NizStek<T>::pop(){
if(_size == 0) throw "Stack is empty";
T oldTop = *_array[_top];
delete _array[_top];
_top--;
_size--;
return oldTop;
}
反向功能:
template<typename T>
void NizStek<T>::reverse() {
NizStek<T> aux;
while(size() != 0){
aux.push(pop());
}
*this = aux;
}
COPY CONSTRUCTOR(OPERATOR =与第一行删除[] _array相同;)
template<typename T>
NizStek<T>::NizStek(const NizStek& rhs){
_size = rhs._size;
_capacity = rhs._capacity;
_niz = new T*[_capacity];
for(int i=0; i<_size ;i++) _array[i] = rhs._array[i];
_top = rhs._top;
}
提前致谢!
答案 0 :(得分:2)
由于你还没有显示它,我猜你是让编译器创建你的拷贝构造函数,它会做一个浅拷贝。所以这个:
template<typename T>
void NizStek<T>::reverse()
{
NizStek<T> aux;
while(size() != 0)
{
aux.push(pop());
}
*this = aux; // Potential problem here!
}
将this
设置为等于aux
的指针值。据推测,你的析构函数释放了内存,所以当aux
超出范围时,this
(this->_array
)中指向的项目不再被分配......所以当你的垃圾邮件被淘汰时你试图取消引用它们。
您可以通过编写自己的复制构造函数并实际执行数据的深层复制(或使用移动语义)来解决这个问题。
修改强>
使用更新的复制构造函数,您似乎还有另一个问题:
_niz = new T*[_capacity];
for(int i=0; i<_size ;i++)
_array[i] = rhs._array[i]; // this is still a shallow copy!
_top = rhs._top;
分配将创建一个指针数组,而不是一个对象数组。因此,您将拥有一组未分配的指针(this
和aux
将指向相同的项目,因此当aux
在其析构函数中清除它们时,您仍然指向垃圾)。我想你想要的是
_niz = new T[_capacity]; // note the lack of *
for(int i=0; i<_size ;i++)
_array[i] = rhs._array[i];
_top = rhs._top;
或者
_niz = new T*[_capacity];
for(int i=0; i<_size ;i++)
{
_array[i] = new T(*rhs._array[i]); // actually do a deep copy
}
_top = rhs._top;
作为旁注,如果您担心效率,您可能想要使用固定大小的数组,或使用链表。每次推送需要新容量的项目时重新分配和复制内存缓冲区对于堆栈结构来说效率非常低。