C++ 指针在退出函数时设置为空指针
我有一个很难理解的阻塞问题。一般来说,我在做一种蚁丘模拟。里面有一条主通道,分成几段,蚂蚁可以从其中的几段进入房间。所有这三个类(通道、段、室)都有一个共同点——收集当前访问它们的蚂蚁。因此有一个抽象类C++ 指针在退出函数时设置为空指针,c++,pointers,vector,null,C++,Pointers,Vector,Null,我有一个很难理解的阻塞问题。一般来说,我在做一种蚁丘模拟。里面有一条主通道,分成几段,蚂蚁可以从其中的几段进入房间。所有这三个类(通道、段、室)都有一个共同点——收集当前访问它们的蚂蚁。因此有一个抽象类AntHolder,它包含vector(仅显示与案例相关的成员): putItem函数与anteter函数类似,但它将Item对象添加到items集合中。(物品如食物,由蚂蚁从一个房间移动到另一个房间。)下面显示了两种功能的实现: bool AntChamber::antEnter(Ant
AntHolder
,它包含vector
(仅显示与案例相关的成员):
putItem
函数与anteter
函数类似,但它将Item
对象添加到items
集合中。(物品如食物,由蚂蚁从一个房间移动到另一个房间。)下面显示了两种功能的实现:
bool AntChamber::antEnter(Ant* ant)
{
if (items.size() + ants.size() == itemCapacity + additionalCapacity) return false;
ants.push_back(ant);
return true;
}
bool AntChamber::putItem(Item* item)
{
if (items.size() == itemCapacity ||
items.size() + ants.size() == itemCapacity + additionalCapacity)
return false;
if (item->getItemKind() == Food) hasFood = true; // Food == enum value
else if (item->getItemKind() == Egg) hasEgg = true; // Egg == enum value
items.push_back(item);
return true;
}
你可以清楚地看到,它们几乎是一样的。但说到它们的效果,有一个关键的、令人惊讶的区别,这就是我的问题的核心
假设我已经建造了一个AntChamber*chamber
。当我运行以下代码时:
Item* item = new Item(Food);
chamber->putItem(item);
Ant* ant = new Ant(chamber);
chamber->antEnter(ant));
,然后,item
和chamber->items.back()
都指向该对象的一些内存。但当我运行类似的代码时:
Item* item = new Item(Food);
chamber->putItem(item);
Ant* ant = new Ant(chamber);
chamber->antEnter(ant));
,然后在这之后,ant
指向对象,但是chamber->ants.back()
指向NULL
我完全无法理解发生了什么,尤其是putItem
和anteter
实际上做了相同的事情:push_back
指针,它是通过参数传递的。我已经尝试在一些更简单的代码中模拟这种情况,例如:
class A { };
class B { };
class C
{
vector<A*> va;
vector<B*> vb;
public:
A* vaBack() { return va.back(); }
B* vbBack() { return vb.back(); }
void addA(A* a) { va.push_back(a); }
void addB(B* b) { vb.push_back(b); }
};
int main(int argc, char** argv)
{
A* a = new A();
B* b = new B();
C* c = new C();
cout << (unsigned int)a << endl;
c->addA(a);
cout << (unsigned int)c->vaBack() << endl;
cout << (unsigned int)b << endl;
c->addB(b);
cout << (unsigned int)c->vbBack() << endl;
delete c;
delete b;
delete a;
}
A类{};
B类{};
C类
{
向量va;
向量vb;
公众:
A*vaBack(){return va.back();}
B*vbBack(){return vb.back();}
void addA(A*A){va.push_back(A);}
void addB(B*B){vb.push_back(B);}
};
int main(int argc,字符**argv)
{
A*A=新的A();
B*B=新的B();
C*C=新的C();
我的天啊,我太瞎了
我按照Shafik Yaghmour的建议做了SSCE,我在做的时候注意到了这个问题
我用了一个思维跳跃,说,chamber->items.back()
或chamber->ants.back()
为空,因为事实上它们不是!但它们在它们的类中受到保护,所以我在这两个类中都编写了一个函数来访问第I项/ant。问题是这个函数。它对从向量的键中给出索引进行了标准的独特防护,但在这样做时犯了一个错误:
if (idx < 0 || ants.size() >= idx) return 0; // SHOULD BE <= !!!
return ants[idx];
if(idx<0 | | ants.size()>=idx)返回0;//您是否检查了chamber->anteter(ant)的返回值)
不是错误的
?因为我们没有一个简短的、自包含的示例,所以很难确定问题:在antEnter中,itemCapacity和additionalCapacity的值是多少?您真的想在antEnter中使用itemCapacity吗?@Shafik Yaghmour-我确实想了。事实并非如此。当我测试它时,两个向量都是空的,两个都是空的容量要高得多-例如10+5。正如你所看到的,我试图简化示例,但我的尝试失败了:)@Sushi271好的,你能把你的代码简化成一个能再现问题的SSCCE吗?似乎问题出在我们没有的代码部分。@Andythonas Cramer-我认为这与案例无关;但如果你问:这个想法是,你们可以用物品填满房间,直到物品容量限制,但必须为蚂蚁留出一些空间,这样它们才能进来。但若物品少于物品容量,那个么更多的蚂蚁可以进来。所以物品容量+额外容量=总容量,蚂蚁和物品都不能超过。但蚂蚁本身并没有其他限制,联合国类似项目。这是进行SSCCE的要点之一,我猜您可能会自己解决它。在许多情况下,尝试在一个较小的示例中演示错误会导致解决问题。