std::out_of_range 在静态 int 变量上

std::out_of_range on static int variable

本文关键字:变量 int 静态 range out of std      更新时间:2023-10-16

我在一个基于 dos 的小型游戏(课程项目(中使用静态变量作为临时计时器。 该变量跟踪状态效果消失之前的圈数。 这是代码:

for (auto &i : v) // <-- code that calls enemyAttack
enemyAttack(i, p, str, i.attack);
break;
void enemyAttack(Enemy &e, playerObject &p, std::array<std::string, NUM_MESSAGES> &str, void(*a)(playerObject &p, std::array<std::string, NUM_MESSAGES> &str)) {
int die = rand() % 100 + 1;
int d = 1;
a(p, str); // <-- Call function which causes the error
...
}
void batAttack(playerObject &p, std::array<std::string, NUM_MESSAGES> &str) {
static int time = 2;
static bool bit = false;
if (rand() % 10 < CHANCE_OF_STATUS_EFFECT && !bit) {
p.damage /= 2;
str[STATUS] += "WEAKENED ";
bit = true;
}
else if (time == 0) {
p.damage *= 2;
str[STATUS].replace(str[STATUS].find("WEAKENED ", 0), 9, "");
time = 2;  // <-- error
bit = false;
}
else if (bit) {
time--;
}
}

我在第二个条件内的行time = 2;收到 std::out_of_range 错误。 此函数通过主攻击函数的函数指针调用。 该错误似乎是随机的,MSVS 报告所有变量在发生错误时具有应有的值。

str[STATUS].replace(str[STATUS].find("WEAKENED ", 0), 9, "");

只是一场等待发生的灾难。让我们先看看内在的发现。

str[STATUS].find("WEAKENED ", 0)

当您经常这样做时,您在短程序中使用值"WEAKED"两次,您会遇到拼写错误,因此最好在此处使用命名值,这样就不会出错。

constexpr const char *WeakenedStr = "WEAKENED ";

,然后使用

str[STATUS].find(WeakenedStr , 0)

其次,这可能会失败,如果未找到字符串,它将返回"npos"(当前为 -1(。所以我们也需要测试一下

auto pos = str[STATUS].find("WEAKENED ", 0);
if (pos != std::string::npos)
str[STATUS].replace(pos, 9, "");

接下来是"9",这是一个神奇的数字,也应该是一个命名值

constexpr const char *WeakenedStr = "WEAKENED ";
const int WeakenedStrLen = strlen(WeakenedStr); // strlen is sadly not constexpr.

auto pos = str[STATUS].find("WEAKENED ", 0);
if (pos != std::string::npos)
str[STATUS].replace(pos, WeakenedStrLen, "");

注意:未经测试的代码,将出现错误。