2017-09-01 6 views
-1

MultipleStackは、複数のスタックをサポートするクラスですが、すべての値を単一の1次元配列に格納します。 push(item, k)itemkスタックにプッシュします。これを正しく行うために、クラスはすべてのスタックの一番上の要素のインデックスを格納する配列topを格納します。 pushは、itemを押した後にtop[k - 1]を1つ増やして、次の項目が正しくプッシュされるようになっています。しかし、ときどき、pushtop[k - 1]を2つ増やしてしまい、その理由を理解できません。C++配列の値が1だけランダムに増加する

#include <cassert> 

class MultipleStack { 
    int * _s; 
    size_t * _top; 
    size_t _nStacks, _size; 

public: 
    MultipleStack(size_t nStacks, size_t size) { 
     _nStacks = nStacks; 
     _size = size * nStacks; 
     _s = new int[size]; 
     _top = new size_t[nStacks]; 
     //Simply sets top = {0, 10, 20, ...} no error here 
     for (size_t i = 0; i < nStacks; i++) { 
      _top[i] = (_size/_nStacks) * i; 
     } 
    } 

    //This is the buggy method 
    void push(int item, size_t k) { 
     size_t beforeSet = _top[k - 1]; 
     _s[_top[k - 1]] = item; 
     size_t afterSet = _top[k - 1]; 
     assert(beforeSet == afterSet); // Fails when beforeSet = 14 
     _top[k - 1] = _top[k - 1] + 1; 
    } 

    static void testImplementation() { 
     //Both, nStacks and size, must be >= 9 
     int nStacks = 10; 
     int size = 10; 
     MultipleStack ms(nStacks, size); 
     for (int i = 1; i <= nStacks; i++) { 
      for (int j = 0; j < size; j++) { 
       ms.push(1, i); 
      } 
     } 
    } 
}; 

int main(int argc, const char * argv[]) { 
    MultipleStack::testImplementation(); 
    return 0; 
} 

長いコードサンプルについてお詫び申し上げます。私はできる限り多くを取り除きましたが、私はそれ以上のことはできませんでした。

+0

デバッガでコードを1行ずつステップ実行する際に、何を観察しましたか? – user0042

答えて

2

私はC-TORでこの行に1個のバグを参照してください。私が正しく理解していれば

_s = new int[size]; 

、_sは、すべてのスタック用のメモリブロックを表し、それ」のサイズは次のようになります。size * nStacks代わりに。これは、後続のデータを上書きする割り当てられたメモリの外部への書き込みにつながる可能性があります(_topアレイはそれらのデータの1つです)。 _sの割り当てを修正してください。

次に、より慎重に変数の名前を付けてみてください。size_sizeを間違えないようにしてください。 _size - >_sizeOfAllStacksなどの名前を変更した場合、これは問題にはなりません。

+0

D'oh。ありがとうございました。私はあなたの答えをStackOverflowが許可するとすぐに受け入れます。 –

+0

@ shikari-shambu - ネーミングに関する詳細:メンバ変数の先頭にアンダースコアを使用すると、少なくともグローバルネームスペース内の実装用に予約されていることを知っている私は混乱します。例えば、VC++は['_msize'](https://msdn.microsoft.com/en-us/library/z2s077bc.aspx)の拡張子を持っており、あなたが使っているものではないことを本当に注意深く見なければなりません。 –

関連する問題