所以我正在尝试学习模板和Fifo和Lifo堆栈的东西。我一直在玩一些处理这个的代码,我可以得到int数据来做我想要的测试,但我不能为我的生活找出如何使用字符串。 我拥有代码的方式一直让我崩溃,但是没有给我任何错误,所以我想我会在这里看看是否有人可以告诉我我做错了什么。这是我的代码:
-----------//my header//---------------------
#include <stdlib.h>
#include <iostream>
#include <string>
#ifndef STACK_H_
#define STACK_H_
template<class T>
class StackTest
{
private:
unsigned int maxSize;
T *stackData;
int top;
public:
StackTest(int size){
stackData = new T[size];//to hold the T type data items
top = -1;//no items on the stack
maxSize = size;//set maximum size that stack can hold
}
virtual ~StackTest(){}
int count(){
return top + 1;
}
bool isEmpty(){
return top == -1 ? true : false;
}
bool isFull(){
return top == maxSize - 1 ? true : false;
}
T* peek(){
if(!isEmpty())//check for empty
return &stackData[top - 1];
}
T* pop(){
if(!isEmpty()){
top -= 1;//decrease the top by 1 to indicate the delete
return &stackData[top];//return deleted item
}
return NULL;
}
void push(T* item){
stackData[top++] = *item;//insert to data array and increase the top by one
}
};
#endif /* STACK_H_ */
-----------//my main//---------------
#include <iostream>
#include <string>
#include "Pair.h"
using namespace std;
int main() {
int dataTest;
string strTest;
StackTest<int> intStack(10);
StackTest<string> stringStack(50);
//Insert data into the stack
dataTest = 3;
intStack.push(&dataTest);
dataTest = 4;
intStack.push(&dataTest);
dataTest = 5;
intStack.push(&dataTest);
dataTest = 6;
intStack.push(&dataTest);
strTest = "test";
stringStack.push(&strTest);
//Show the top item
cout << *intStack.peek() << endl;
cout << *stringStack.peek() << endl;
//Pull the top item out (twice)
intStack.pop();
intStack.pop();
//Show the new top item
cout << *intStack.peek() << endl;
return 0;
}
所以,如果有人想给我一些指示,我会非常感激,谢谢。
答案 0 :(得分:0)
您的实施存在一些问题。其中最微妙的是push()
成员函数:
void push(T* item){
stackData[top++] = *item; //insert to data array and increase the top by one
// ^^
// You want pre-increment here!
}
这是递增top
并使用旧值作为stackData
的索引。由于当堆栈为空时top
为-1
,您的程序实际上正在执行:
stackData[-1] = *item;
top = 0;
毋庸置疑,第一项任务会导致未定义的行为。
未定义行为的另一个来源是peek()
成员函数,当堆栈为空时它不会返回任何内容:
T* peek(){
if(!isEmpty())//check for empty
return &stackData[top - 1];
}
根据C ++ 11标准的第6.6.3 / 2段:
[...]离开函数末尾相当于没有值的返回;这导致未定义 价值回归函数中的行为。
但这不是唯一的问题:另一个问题是访问stackData
:
return &stackData[top - 1];
当top
不等于或大于1时,这也会导致未定义的行为,因为您将获取位于数组中负数地址的(非)对象的地址。 / p>
另外,我建议重写isEmpty()
和isFull()
,如下所示:
bool isEmpty(){
return (top == -1);
}
bool isFull(){
return (top == maxSize - 1);
}
作为一般建议,当堆栈为空时,请考虑不要为-1
使用值top
。 As Ben Voigt mentions in the comments,这会导致很多错误。
此外,as pointed out by DyP,您的析构函数不会释放构造函数中分配的内存,因此您的StackTest
对象正在泄漏内存。在这样做之后,既然我们就这样做了,你可能想看一下所谓的Rule of Three,你的程序会违反。