1

AMXをベースにしたSA-MPのプラグインを書いていますが、厄介な問題が発生しました。要素を検索して削除するために、両端キューと関数を使用しています。(以下のように)

enum PARAM_TYPE {
    PARAM_TYPE_CELL,
    PARAM_TYPE_ARRAY,
    PARAM_TYPE_STRING,
};

struct params_s {
    enum PARAM_TYPE type;
    struct params_s * next;
    cell free;
    cell numData;
    cell arrayData[0];
};

struct timer_s {
    AMX * amx;
    int id, func, interval, repeat;
    long long unsigned int trigger;
    struct params_s * params;
};

std::deque<struct timer_s *> gTimers;

void DestroyTimer(struct timer_s * t) {
    for (int i = 0; i != gTimers.size(); ++i) {
        if (t == gTimers[i]) {
            gTimers.erase(gTimers.begin() + i);
            break;
        }
    }
}

DestroyTimer()を呼び出すと、次のエラーが発生します。

Debug Assertion Failed!
Expression: deque subscript out of range

要素を追加したり、読み取ったり、変更したりすることはできますが、削除することはできません。

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

4

2 に答える 2

2

消去削除イディオムを使用する必要があります。

void DestroyTimer(struct timer_s * t)
{
  gTimers.erase(remove(gTimers.begin(), gTimers.end(), t), gTimers.end()); 
}
于 2012-10-15T13:01:02.860 に答える
1

実際のエラーを見ずに、慣用的な方法は次のようになります。

gTimers.erase(std::remove(gTimers.begin(), gTimers.end(), t), 
              gTimers.end());

これは、現在行っていることよりも安全で高速です (重複をキャッチし、再割り当てする必要はありません)。

これは Erase-Remove イディオムと呼ばれます。

実際のデバッグ アサーションについて: デバッグ イテレータは標準の拡張機能であり、場合によっては壊れている可能性があります。

注意:deleteタイマーが両端キューによって所有されている場合は、タイマーを呼び出して、メモリ リークを防ぐ必要があります。

于 2012-10-15T13:01:19.843 に答える