下面是我正在尝试实现的堆栈数据结构的代码片段。
由于某些原因,当我删除currentArray
时,newArray
也会被删除,因为下面的代码会给我一个运行时错误,其中包含newArray
和{{1}的内容是垃圾值。
我不确定为什么会这样。
非常感谢有关我为什么会收到此错误的任何见解,以及下面的currentArray
实施是从基本角度出发的。
push()
答案 0 :(得分:2)
在push
功能中,在else
区块中执行
currentArray = newArray;
因此,currentArray
和newArray
都指向同一件事! (你自己做的)。
因此,当您执行delete [] currentArray
时,您无需删除newArray
,因为该内存已被删除。这就是为什么你的程序发出错误,你试图删除已被删除的内存!!
此外,在您的推送功能中,您执行::
currentArray = new T[size];
currentArray = newArray;
我相信你的class
,currentArray
是pointer
,而new
也会返回指向新分配内存的指针。因此,如果您希望currentArray
指向newArray
,则只需执行currentArray = newArray
而无需为currentArray
分配内存。
此外,您还可以::
newArray = new T[size];
copy(currentArray, currentArray + size, newArray);
在if块中,我相信您正在将数据currentArray
复制到newArray
,因此,在您将数据从currentArray
复制到newArray
之后,您需要delete
以前为currentArray
分配了内存,否则是内存泄漏(程序中的故障导致丢弃内存,导致性能下降或失败)。 delete
记忆总是好的,这是没用的。
因此,我建议您在此之后添加delete [] currentArray
语句。
所以,你的最终代码看起来像这样::
// Destructor
~Stack()
{
/*
*if ((size > 0) && (currentArray) != NULL) -->
*deleting a NULL pointer is completely defined!
*So, in your constructor if you are initializing
*currentArray to NULL you need not have any if condition.
*/
delete[] currentArray;
}
inline void push(T value)
{
if (isEmpty())
{
size++;
currentArray = new T[size];
currentArray[size - 1] = value;
}
else
{
size++;
newArray = new T[size];
copy(currentArray, currentArray + size, newArray);
delete [] currentArray; //EDIT
newArray[size - 1] = value;
//currentArray = new T[size]; --> Deleted Line
currentArray = newArray;
}
}
注意:: 如果您的编译器符合C ++ 11,您应考虑使用nullptr
而不是NULL
,原因如下:{{3 }}
答案 1 :(得分:2)
首先,您不需要在析构函数中进行检查。
~Stack() {
delete [] currentArray;
delete [] newArray;
}
推动有几个问题:
value
,这可能很昂贵。你应该通过参考传递。size
中使用copy()
,这意味着您将原始内存复制到newArray
的最后一个广告位。这可能是良性的(T = int +运气)或灾难性的(T = std :: string)。newArray
内需要push()
。它应该是局部变量,而不是成员变量。new T[size]
。其中一个泄漏。这是一个重新设计的版本:
class Stack {
public:
…
inline void push(const T& value) {
if (size_ == capacity_) {
capacity_ = capacity_ ? capacity_ * 2 : 1;
T* dest = new T[capacity_];
copy(data_, data_ + size_, dest);
delete [] data_;
data_ = dest;
}
data_[size_++] = value;
}
…
private:
T* data_ = nullptr;
size_t size_ = 0, capacity_ = 0;
};
这绝不是一个坚实的,工业级的代码。它不涉及异常安全,复制避免(除其他外,需要额外的重载:push(T&& value)
)以及一系列其他细微之处。事实上,我甚至没有检查它编译!它可能适用于玩具项目,但在现实世界中,您应该只使用std :: stack。
答案 2 :(得分:0)
也许我错过了一些东西,但如果if
陈述证明是真的,那么它无论如何都会删除。
另外,从基本的角度来看,为什么你没有:
if ((size > 0) && (currentArray != NULL) && (newArray != NULL))
这不是一个大问题,但不匹配的括号是敌人。
答案 3 :(得分:0)
@ user007这是我的pop()函数。
// Remove an element from the stack
inline const T& pop()
{
if (size > 0)
{
T value;
size--;
value = data[size];
T* dest = new T[size];
// Copy the contents of the old array into the new array
copy(data, data + (size), dest);
delete[] data;
data = dest;
return value;
}
return NULL;
}