我是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);
}
答案 0 :(得分:3)
以下列出了我注意到的一些事项:
STACKMAX
是常数。如果您正在扩展堆栈,您将如何跟踪当前的大小?values
成员是固定大小的数组。如果不改变声明和分配方式,您将无法动态更改动态大小。calloc()
使用您指定的字节数分配新的内存块。您需要以某种方式将现有堆栈复制到新内存块中,并释放前一个堆栈。STACKMAX
的调用中仅分配calloc()
个字节。如果sizeof T
不是T
,您可能希望按char
进行扩展。一旦你解决了这些重点,你就会有很多细节需要解决。祝你好运。
答案 1 :(得分:1)
问题是你不想重新分配堆栈的顶部。相反,您希望分配一个新的值数组,该数组足够大以容纳新值。此外,由于您需要重新分配数组,values
应该是一个指针。
但是我们怎么忘记了这一切。如果我们使用的是c ++,那么让我们使用c ++为我们提供的东西,让我们的生活更轻松。完成之后,如果你真的觉得有需要,那就试试吧。
我所指的其中一件事是您使用calloc
。使用calloc
是错误的想法,尤其是在使用模板时。问题是,由于calloc
没有类型信息,因此它不会像调用构造函数那样执行基本操作。构造函数在OOP中非常非常重要,因为它们保证了对象在创建时的不变性。相反,请使用new[]
关键字,例如
values = new T[STACKMAX];
这将分配T
STACKMAX
长度的数组。当然,正如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
的工作方式(以及网上有大量解释/文档)感到非常满意,然后会尝试自己实现这些功能。最重要的是,如果您确切知道它应该如何表现,那么实现数据结构会容易得多。
答案 2 :(得分:0)
我会声明您的值,如
T* vaules;
然后使用new来创建它而不是calloc。您需要跟踪堆栈的顶部和大小。正如Greg所说,当你增长堆栈时,请确保并复制数据并清理旧数据。