简体   繁体   English

模板堆栈和LIFO C ++

[英]Template Stack and LIFO C++

So I'm trying to learn about Templates and the Fifo and Lifo stack stuff. 因此,我试图了解模板以及Fifo和Lifo堆栈内容。 I've been playing around with some code that deals with this, and I can get the int data to do what I want for testing but I can't for the life of me figure out how to get this to work with a string. 我一直在处理一些与此相关的代码,并且我可以获取int数据来做我想测试的事情,但是我一生都无法弄清楚如何使它与字符串一起工作。 The way I have the code keeps crashing on me, but doesn't give me any errors, so I thought I'd pop in here and see if anybody could tell me what I'm doing wrong. 我拥有代码的方式不断使我崩溃,但是没有给我任何错误,所以我认为我会在这里弹出,看看是否有人可以告诉我我在做什么错。 Here's my code: 这是我的代码:

-----------//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;
}

So if anyone feels like giving me some pointers I would really appreciate it, thanks. 因此,如果有人想给我一些指导,我将非常感激,谢谢。

There are a few issues with your implementation. 您的实现存在一些问题。 One of the most subtle is in the push() member function: 最微妙的之一是push()成员函数:

void push(T* item){
    stackData[top++] = *item; //insert to data array and increase the top by one
    //           ^^
    //           You want pre-increment here!
}

This is incrementing top and using the old value as an index into stackData . 这将递增top并使用值作为stackData的索引。 Since top is -1 when the stack is empty, your program is actually doing: 由于堆栈为空时top-1 ,因此您的程序实际上正在执行:

stackData[-1] = *item;
top = 0;

Needless to say that the first assignment results in undefined behavior. 不用说,第一次分配会导致未定义的行为。

Another source of undefined behavior is the peek() member function, which does not return anything when the stack is empty: 不确定行为的另一个来源是peek()成员函数,该函数在堆栈为空时不返回任何内容:

T* peek(){
    if(!isEmpty())//check for empty
        return &stackData[top - 1];
}

Per paragraph 6.6.3/2 of the C++11 Standard: 根据C ++ 11标准的6.6.3 / 2段:

[...] Flowing off the end of a function is equivalent to a return with no value; [...]从函数的结尾流出就等于没有值的返回; this results in undefined behavior in a value-returning function. 这导致返回值函数中的行为不确定。

But that's not the only issue: the other problem is with the access of stackData : 但这不是唯一的问题:另一个问题是访问stackData

return &stackData[top - 1];

When top is not equal to or greater than one, this will also result in undefined behavior, since you would be taking the address of a (non-)object located at a negative address in the array. top不等于或大于1时,这也会导致未定义的行为,因为您将获取位于数组负地址中的(非)对象的地址。

Also, I suggest to rewrite isEmpty() and isFull() as follows: 另外,我建议重写isEmpty()isFull() ,如下所示:

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

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

As a general advice, consider not using the value -1 for top when the stack is empty. 作为一般建议,请考虑在堆栈为空时不要将值-1用于top As Ben Voigt mentions in the comments , this is leading you to a lot of off-by-one errors. 正如Ben Voigt在评论中提到的那样 ,这会导致您出现许多不一的错误。

Also, as pointed out by DyP , your destructor is not freeing the memory allocated in the constructor, so your StackTest object is leaking memory. 另外, 正如DyP所指出的那样 ,析构函数不会释放在构造函数中分配的内存,因此您的StackTest对象正在泄漏内存。 And after doing that, since we're at it, you may want to have a look at the so-called Rule of Three , that your program would be violating. 然后,既然如此,您可能想要看一看所谓的“三规则” ,即您的程序将被违反。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM