动态堆栈内存重新分配
我对C++相当陌生,对指针也很陌生。我目前正在研究一个堆栈,并试图重新分配堆栈的内存,因为堆栈的大小达到顶端,但是我遇到了问题。我已经在Google和堆栈溢出方面做了很多研究,并且发现了一些有用的信息,但是因为我对堆栈和C++都很陌生,所以我仍然遇到问题。我希望一些明亮而聪明的人至少能指引我朝着正确的方向前进。动态堆栈内存重新分配
现在...这是我的代码。
#include <iostream>
#define STACKMAX 20
using namespace std;
template <class T> class StackTemplated {
private:
int top;
T values[STACKMAX];
public:
StackTemplated();
void push(T i);
T pop(void);
bool empty(void);
};
template <class T> StackTemplated<T>::StackTemplated() {
top = -1;
}
template <class T>void StackTemplated<T>::push(T i) {
if (top == STACKMAX - 1) {
// reallocate top of stack. (this is the area I'm having issues)
char * string1;
string1 = (char *)calloc(STACKMAX, sizeof(char));
if (top == STACKMAX - 1) {
cout << "The stack didn't re-allocate.";
exit(1);
}
} else {
top++;
values[top] = i;
}
}
template <class T> T StackTemplated<T>::pop(void) {
if (top < 0) {
printf("%", "Stack underflow!");
exit(1);
} else {
return values[top--];
}
}
template <class T> bool StackTemplated<T>::empty() {
return (top == -1);
}
问题是你不想重新分配堆栈的顶部。相反,你想分配一个足够大的新数组来保存新值。另外,由于您需要重新分配阵列,values
应该是一个指针。
但是我们如何忘记这一切。如果我们使用C++,让我们使用C++提供给我们的东西,让我们的生活更轻松。在完成之后,如果你真的觉得需要,可以试着打开它。
我指的是你使用calloc
。使用calloc
是一个不好的想法,特别是在使用模板时。问题是因为calloc
没有类型信息,所以它不会像调用构造函数那样做一些基本的事情。构造函数是在OOP中非常重要的,因为它们保证了对象在创建时的不变性。而是,使用new[]
关键字,像
values = new T[STACKMAX];
该分配的STACKMAX
长度的T
阵列。当然,正如Greg指出的那样,您应该重新考虑使用STACKMAX
,并改用变量。另外,values
不应该是一个静态数组,而应该改为T*
。
我指的另一件事是,你真的想要实现一个根据需要动态增长的数组。在C++中,我们称这种结构为vector
。如果您使用矢量,您的整个代码缩小到
#include<iostream>
#include<vector>
using namespace std;
template<class T> class StackTemplated {
private:
std::vector<T> vec;
public:
StackTemplated() { } // the constructor is trivial; in fact, you can leave it out if you want
void push(T i);
T pop(void);
bool empty(void);
};
template<class T>
void StackTemplated<T>::push(T i) {
vec.push_back(i);
}
template<class T>
T StackTemplate<T>::pop(void) {
T top = vec.back();
vec.pop_back();
return top;
}
template<class T>
bool StackTemplate<T>::isEmpty(void) {
return vec.size() == 0;
}
就是这样。如果你可以使用现有的数据结构来实现新的数据结构,那么它就少了很多。
一旦你对vector
的工作方式(以及网络上的大量解释/文档)非常满意,然后尝试自己实现功能。底线是,如果你确切地知道它应该如何表现,实现一个数据结构要容易得多。
这里有几件事情,我注意到一个列表:
-
STACKMAX
是一个常数。如果你正在扩展堆栈,你将如何跟踪它目前有多大? -
values
成员是一个固定大小的数组。您将无法动态更改其大小,而无需更改其声明和分配方式。 -
calloc()
以您指定的字节数分配新的内存块。你需要以某种方式将现有的堆栈复制到新的内存块中,并释放前一个堆栈。 - 您在拨打
calloc()
时只分配STACKMAX
字节。如果T
不是char
,您可能希望按比例缩小sizeof T
。
一旦你解决了这些重要问题,会有很多细节供你修复。祝你好运。
我将宣布自己的价值观像
T* vaules;
然后使用新创建它不释放calloc。您需要跟踪堆栈的顶部和大小。正如格雷格在堆栈中说的那样,确保将数据复制并清理旧数据。
请注意,“C/C++”不是一种语言。 C和C++是独立的语言;在这种情况下,您正在使用C++。 – Cameron
我已经删除了问题和标签中对C的引用。 –
让'pop()'返回一个对象以及弹出一个对象是一个相当不好的设计。这使得以异常安全的方式使用堆栈非常困难(这使得强壮的异常安全保证特别难以实现),因为从堆栈中弹出该值(其修改堆栈)的操作之后是操作将返回值复制到调用者的代码中(可能会抛出)。 (有关此事的更多讨论,请参见[这里](http://www.gotw.ca/gotw/008.htm)。) – Mankarse