模板栈和LIFO

Template Stack and LIFO C++

本文关键字:LIFO      更新时间:2023-10-16

所以我试图了解模板和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;
}

如果有人愿意给我一些建议,我将非常感激,谢谢。

您的实现存在一些问题。其中最微妙的是在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时,这也会导致未定义的行为,因为您将获取位于数组中负地址的(非)对象的地址。

另外,我建议重写isEmpty()isFull()如下:

bool isEmpty(){
    return (top == -1);
}
bool isFull(){
   return (top == maxSize - 1);
}

作为一般建议,当堆栈为空时,考虑不使用-1作为top的值。正如Ben Voigt在评论中提到的那样,这会导致很多偏差。

同样,正如DyP所指出的,析构函数没有释放构造函数中分配的内存,因此StackTest对象正在泄漏内存。在做了这些之后,既然我们在这里,你可能想看看所谓的三法则,你的程序可能会违反。