0

だから私はテンプレートと 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;
}

ですから、誰かが私にいくつかの指針を与えてくれると感じたら、本当に感謝します、ありがとう.

4

1 に答える 1

0

実装にはいくつかの問題があります。最も微妙なものの 1 つは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;

言うまでもなく、最初の代入によって未定義の動作が発生します。

未定義の動作のもう 1 つの原因は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を使用しないことを検討してください。Ben Voigt がコメントで言及しているように、これにより多くのオフバイワン エラーが発生します。top

また、DyP で指摘されているように、デストラクタはコンストラクタで割り当てられたメモリを解放していないため、StackTestオブジェクトがメモリをリークしています。そして、それを行った後、私たちはそれに取り組んでいるので、プログラムが違反している、いわゆる3 の規則 を見たいと思うかもしれません。

于 2013-05-13T23:28:10.520 に答える