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 idiom

对于实际的调试断言:调试迭代器是标准扩展,在某些情况下可能会损坏。

delete注意:如果它由双端队列拥有,您想调用计时器,以防止内存泄漏。

于 2012-10-15T13:01:19.843 回答