我遇到了一个问题,我的代码在试图使用列表的size()函数时发生了分歧。根据stackoverflow的建议:-)我构建了一个最小的情况,其中发生了segfault(在下面的调用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中删除数组的设置时,它工作正常,所以这看起来是个问题。我做错了什么?
答案 0 :(得分: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;
之间循环。
答案 1 :(得分:2)
您正在数组范围之外访问。这样做会导致未定义的行为,因此之后发生的任何事情都没有逻辑解释。数组的大小为99,因此最后一个索引为98.但是,for
循环最多为99。
使数组大小为100:
int xpCalcArray[100];
或者将您的for
条件更改为i < 99
。
答案 2 :(得分:2)
您通过尝试修改第2→第100个元素(而不是第1个→第99个)来覆盖99 int
的数组。
在你的情况下,这恰好覆盖了std::list<Thing*>
中的一些内存(它在数组后直接存在于内存中 - 并不总是,但今天显然适合你),因此,当你尝试使用这个列表,当它的内部成员数据不再像它想象的那样时,一切都会崩溃。
答案 3 :(得分:1)
你xpCalcArray
定义为0到98(99个元素大)。
你的循环从0到99,需要100步。
最后一个循环周期,将xpCalcArray
写入位置99,该位置不存在。这(间接)导致您的细分错误,如the answer of Lightness Races in Orbit所示。
因此,将xpCalcArray
的大小增加1:
int xpCalcArray[100];