我遇到了一个问题,我的代码在尝试使用列表的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构造器中删除数组的设置时,它工作得很好,所以这看起来是问题所在。我做错了什么?
您正在越界访问您的数组,这导致未定义行为。数组
的有效索引范围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];
您正在访问数组的边界之外。这样做会导致未定义的行为,因此对随后发生的任何事情都没有合理的解释。数组的大小是99,所以最后一个索引是98。然而,您的for
循环上升到99。
让你的数组大小为100:
int xpCalcArray[100];
或将for
条件更改为i < 99
您试图修改第2个→第100个元素(而不是第1个→第99个),从而覆盖了99个int
s数组。
在你的例子中,这恰好覆盖了std::list<Thing*>
中的一些内存(CC_6直接存在于数组—不总是,但显然今天对你来说),因此,当你试图使用列表时,当它的内部成员数据不再是它所认为的那样时,所有的地狱都爆发了。
您的xpCalcArray
定义从0到98(即99个元素的大小)
你的循环从0到99,走100步。
最后一个循环,在位置99写入xpCalcArray
,这个位置不存在。这(间接地)导致你的分割错误,如在轨道上的轻竞赛的答案所示。
那么,将xpCalcArray
的大小增加1:
int xpCalcArray[100];