1

私はC++で作業しています。スタックの最大容量を変更する方法に取り組んでいますが、発生するエラーについて混乱しています。以下は私の方法です。

void Stack::setCapacity(unsigned newCapacity){
if(newCapacity< this->getSize()){
    throw StackException("setCapacity()", 
    "the size is larger than the desired capacity");
} else {
    if(newCapacity != myCapacity){
        Item * tempArray = new Item[newCapacity];
        if(newCapacity < myCapacity){
            for(unsigned i=0; i<newCapacity;i++){
                tempArray[i] = myArray[i];
            }
        } else if (newCapacity > myCapacity) {
            for(unsigned i=0; i<myCapacity; i++){
                tempArray[i] = myArray[i];
            }
        }
        for(unsigned i=0; i<newCapacity; i++){
            myArray[i] = tempArray[i];
        }
        delete tempArray;
    }
    myCapacity = newCapacity;
} 
}

setCapacity( ) メソッドが機能することをテストするためのテスト メソッドも作成しました。

void StackTester::setCapacityTest() {
cout << "- setCapacity... " << flush;

// empty stack
Stack st7(5);
assert(st7.getSize() == 0);
assert(st7.getCapacity() == 5);
st7.setCapacity(7);
assert(st7.getCapacity() == 7);
cout << " 1 " << flush;

// partially filled stack - larger capacity
Stack st8(5);
assert(st8.getCapacity() == 5);
st8.push(3);
st8.push(4);
st8.setCapacity(7);
assert(st8.getCapacity() == 7);
assert(st8.getTop() == 4);
st8.pop();
assert(st8.getTop() == 3);
cout << " 2 " << flush;

// size larger than new capacity
try{
Stack st9(3);
st9.push(7);
st9.push(4);
st9.push(11);
assert(st9.getSize() == 3);
st9.setCapacity(2);
cerr << "setCapacity's new capacity is larger than the size";
exit(1);
} catch(StackException& se){
    cout << " 3 " << flush;
}

// partially filled stack - smaller capacity
Stack st10(5);
assert(st10.getCapacity() == 5);
st10.push(1);
st10.setCapacity(2);
assert(st10.getCapacity() == 2);
assert(st10.getTop() == 1);
cout << " 4 " << flush;

// fully filled stack - larger capacity
Stack st11(2);
assert(st11.getCapacity() == 2);
st11.push(3);
st11.push(7);
assert(st11.getTop() == 7);
st11.setCapacity(3);
assert(st11.getCapacity() == 3);
cout << " 5 " << flush;

cout << " Passed!" << endl;
}

残りをコメントアウトしてテストの各セクションを個別に実行すると、すべて正常に動作します。テストの各セクションに合格します。ただし、セクションを結合してテスト全体を実行しようとすると、次のエラーが発生します。

* glibc が検出されました ** * /home/.../StackProject: malloc(): メモリ破損 (高速): 0x0000000001e86030 *

デバッガーを使用して、問題をスタック内の myArray の作成に絞り込みました。たとえば、テストで " 1 " を正常に実行した後、" 2 " の st8(5) で myArray を作成すると、プログラムがクラッシュします。

私の混乱の主な原因は、各セクションは個別に通過しますが、まとめて通過するわけではないという事実によるものです。私はそれについて何をすべきかわからない。私の方法は間違って書かれていますか?もしそうなら、どのように修正すればよいですか?

ありがとうございました。

4

2 に答える 2

5

You have

delete tempArray;

But it's an array, so you have to do:

delete [] tempArray;

(although I have no idea what this function is doing or why... )

于 2014-10-26T02:43:09.087 に答える
4

setCapacityの次のコード ブロックに、次の問題があります。

  if(newCapacity != myCapacity){
     Item * tempArray = new Item[newCapacity];
     if(newCapacity < myCapacity){
        for(unsigned i=0; i<newCapacity;i++){
           tempArray[i] = myArray[i];
        }
     } else if (newCapacity > myCapacity) {
        for(unsigned i=0; i<myCapacity; i++){
           tempArray[i] = myArray[i];
        }
     }

     // When newCapacity > myCapacity, myArray does not
     // have enough space for this loop.
     // Say myCapacity = 5 and newCapacity = 7
     // Accessing myArray[5] and myArray[6] is a problem.

     for(unsigned i=0; i<newCapacity; i++){
        myArray[i] = tempArray[i];
     }

     // You are deleting the newly allocated array, even though you are using
     // the wrong delete operator.
     // myArray still points to the old allocated memory.
     delete tempArray;
  }

必要なものは次のとおりです。

  if(newCapacity != myCapacity){
     Item * tempArray = new Item[newCapacity];
     if(newCapacity < myCapacity){
        for(unsigned i=0; i<newCapacity;i++){
           tempArray[i] = myArray[i];
        }
     } else if (newCapacity > myCapacity) {
        for(unsigned i=0; i<myCapacity; i++){
           tempArray[i] = myArray[i];
        }
     }

     // Need to delete the old array and keep the new array.

     Item* oldArray = myArray;
     myArray = tempArray;

     // Use the array delete operator, not the simple delete operator.
     delete [] oldArray;
  }
于 2014-10-26T04:07:28.743 に答える