2017-09-01 96 views
-1

MultipleStack是一個支持多個堆棧的類,但將其所有值存儲在單個一維數組中。 push(item, k)item推到k堆棧上。爲了正確執行此操作,類將存儲一個數組top,該數組存儲每個堆棧中最頂層元素的索引。 push在推入item之後,應該將top[k - 1]增加1,以便正確推送下列項目。但是,有時,push增加了top[k - 1]兩個,我無法找出原因。C++數組值隨機增加一個

#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

當你用調試器逐行執行代碼時,你觀察到了什麼? – user0042

回答

2

我看到在這條線一個錯誤在C-TOR:

_s = new int[size]; 

如果我理解正確的_s代表所有的堆內存塊,所以它的大小應該是:size * nStacks代替。這可能會導致在分配的內存之外進行寫入,從而覆蓋後續的數據(_top數組就是其中一個數據)。修復_s分配,你應該很好。

下一次嘗試以更小心的方式命名變量,因此您不會錯過size_size這麼容易。如果你重命名爲_size - >_sizeOfAllStacks或者其他東西,這不會成爲問題。

+0

D'oh。謝謝。只要StackOverflow允許,我會盡快接受您的答案。 –

+0

@ shikari-shambu - 關於命名的更多信息:對成員變量使用前導下劃線至少讓我感到困惑,因爲我知道這些名字是爲實現保留的(在全局命名空間中)。例如VC++有一個['_msize'](https://msdn.microsoft.com/en-us/library/z2s077bc.aspx)擴展名,我必須仔細閱讀才能看到那不是你正在使用的。 –