7

リストの size() 関数を使用しようとすると、コードでセグメンテーション違反が発生するという問題がありました。stackoverflow のアドバイスで :-) セグメンテーション違反が発生する最小のケースを作成しました (以下の inventory.size() の呼び出しで)。それは:

#include <list>

class Thing {};

class Player {
private:
  int xpCalcArray[99];
  std::list<Thing*> inventory;

public:
  Player();

  int addToInv(Thing& t); // return 1 on success, 0 on failure
};

Player::Player() {
  // set up XP calculation array
  for (int i=1; i<100; i++) {
    if (i<=10) {
      xpCalcArray[i] = i*100;
    }
    if (i>10 && i<=50) {
      xpCalcArray[i] = i*1000;
    }
    if (i>50 && i<=99) {
      xpCalcArray[i] = i*5000;
    }
  }
}

int Player::addToInv(Thing& t) {
  if (inventory.size() == 52) {
  return 0;
  } else {
      inventory.push_back(&t);
  }
  return 1;
}

int main(int argc, char *argv[]) {
  Thing t;
  Player pc;
  pc.addToInv(t);
  return 1;
}

Player cosntructor で配列の設定を削除すると、正常に動作することに気付きました。これが問題のようです。私は何を間違っていますか?

4

4 に答える 4

4

範囲外で配列にアクセスしているため、未定義の動作が発生します。この配列の有効なインデックス範囲

int xpCalcArray[99];

は0から98です。ここでインデックス99にアクセスしています。

if (i>50 && i<=99) {
  xpCalcArray[i] = i*5000;
}

あなたの外側のループは

for (int i=0; i<99; i++) { ... }

最初の要素に実際にアクセスしたいという前提ですが、私は0から始めていることに注意してください。

次に、最終的な条件を次のように簡略化できます。

if (i>50) {
  xpCalcArray[i] = i*5000;
}

サイズ100のアレイを使用する場合は、次のものが必要です。

int xpCalcArray[100];

次に、の間でループしますint i=0; i<100;

于 2013-02-28T10:49:28.503 に答える
2

配列の境界外にアクセスしています。これを行うと、未定義の動作が発生するため、その後に発生することについて論理的な説明はありません。配列のサイズは99であるため、最後のインデックスは98です。forただし、ループは最大99になります。

配列のサイズを100にします。

int xpCalcArray[100];

または、for条件をに変更しますi < 99

于 2013-02-28T10:50:06.273 に答える
2

int2 番目→ 100 番目の要素 (1 番目→ 99 番目ではなく) を変更しようとして、99 の配列を上書きしています。

あなたの場合、これはたまたま内の一部のメモリを上書きしますstd::list<Thing*>(配列の直後のメモリに存在します—常にではありませんが、明らかに今日のあなたにとってはそうです)。したがって、リストを使用しようとすると、その内部メンバーがデータはもはやそれが思っていたものではありません。

于 2013-02-28T10:51:42.293 に答える
1

あなたxpCalcArrayは 0 から 98 まで定義されます (99 要素の大きさ)。

ループは 0 から 99 までで、100 ステップです。

xpCalcArray最後のループ サイクルは、存在しない場所 99 に書き込みます。Lightness Races in Orbit の回答が示すように、これは (間接的に) セグメンテーション違反を引き起こします。

xpCalcArrayしたがって、 のサイズを1増やします。

int xpCalcArray[100];
于 2013-02-28T10:52:00.223 に答える