【发布时间】:2014-12-06 05:33:08
【问题描述】:
我有一个对象指针向量,我在循环更新对象时添加和删除它。我似乎无法从向量中删除已“死亡”的对象而不会导致内存错误。我不确定我做错了什么。下面列出的是我的更新方法和它的子方法。
void Engine::update(string command){
if(getGameOver()==false){
for(p=objects.begin();p!=objects.end();p++){
spawnUpdate(command);
//cout<<"Spawn"<<endl;
objectUpdate(command);
//cout<<"object"<<endl;
scrollUpdate(command);
// cout<<"scroll"<<endl;
killUpdate(command);
//cout<<"kill"<<endl;
}
}
}
void Engine::killUpdate(std::string command){
if((*p)->getIsDead()==true){delete *p;}
}
void Engine::objectUpdate(string command){
(*p)->update(command,getNumObjects(),getObjects());
if(((*p)->getType() == PLAYER)&&((*p)->getPosX()>=getFinishLine())){setGameOver(true);}
}
void Engine::scrollUpdate(string command){
//Check player position relative to finishLine
if(((*p)->getType() == PLAYER)&&((*p)->getPosX()>(SCREEN_WIDTH/2))){
(*p)->setPosX((*p)->getPosX()-RUN_SPEED);
setFinishLine(getFinishLine()-RUN_SPEED);
for(q=objects.begin();q!=objects.end();q++){
//Shift objects to pan the screen
if((*q)->getType() == OPPONENT){(*q)->setPosX((*q)->getPosX()-RUN_SPEED);}
if((*q)->getType() == BLOCK){(*q)->setPosX((*q)->getPosX()-RUN_SPEED);}
}
}
}
void Engine::spawnUpdate(string command){
if(command.compare("shoot")==0){
cout<<"Bang!"<<endl;
if((*p)->getType() == PLAYER){objects.push_back(new Bullet((*p)->getPosX(),(*p)->getPosY(),(*p)->getState()));cout<<"Bullet success "<<endl;}
}
}
【问题讨论】:
-
您需要从
std::vector中删除已删除的内存,否则下一轮您将测试未分配的内存。否则,您可以将它们设置为nullptr,并在使用它们之前检查nullptr。 (或者在处理完之后从std::vector中删除所有nullptr元素)。 -
第一件事是命名变量比
p和q更具描述性。其次,更好地格式化你的代码,因为代码很难阅读。 -
问题是你在循环你的向量时改变了你的向量的大小。这将使迭代器无效——不要编写代码来改变向量的大小,同时你在同一个向量上循环——问题不仅仅是
delete调用。 -
我该如何解决这个问题? update 方法在游戏未结束时不断调用,我需要遍历向量才能知道需要删除哪些对象。
-
管理此问题的一种方法是在处理
std::vector时将新元素添加到单独的std::vector并使用nullptr标记要删除的元素。然后在完成整个std::vector的处理后,通过擦除nullptr元素并从另一个向量中附加新元素来进行更改。 (或从新的std::vector替换nullprt元素并附加/删除差异)。
标签: c++ pointers object vector delete-operator