我正在生成一个大型游戏树,描绘两个节点之间的拍卖场景(称为type1和type2。生成的树完全正常,直到我到达第四级节点。
#include <iostream>
#include <vector>
#include <queue>
#define LEVEL 8
using namespace std;
class payoff_node{
int agent_1;
int agent_2;
};
class node{
public:
/* constructor to set payoff_ptr to NULL */
node() {
payoff_ptr = NULL;
parent = NULL;
}
/* print the information about the node */
void printNode(){
cout << "type: " << type << "\t" << "level: " << level << "\t" << "purse: $" << purse << "\t" << "parent_bid: " << parent_bid << "\t" << "parent:" << parent->getType() << "\t" << endl;
/*for (int i = 0; i < actions.size() ; i++){
cout << actions[i] << endl;
}*/
}
void setType(int t){ type = t; }
void setLevel(int l){ level = l; }
void setPurse(int p){
purse = p;
/* Depending on the purse value the action space is decided */
for(int i = 0; i <= purse ; i++){
actions.push_back(new node);
}
}
void setParentBid(int bid){ parent_bid = bid; }
void setParent(node &parent_node){ parent = &parent_node; }
int getLevel(){ return level; }
int getParentBid(){ return parent_bid; }
int getPurse(){ return purse; }
node** getParent(){ return &parent; }
int getType(){ return type; }
vector<node*> actions;
private:
int type;
int level;
int purse;
int parent_bid;
node* parent;
payoff_node* payoff_ptr;
};
int main(int argc, char* argv[]){
bool D = false;
/* Make the root node and set its properties */
node root_node;
root_node.setType(1);
root_node.setLevel(1);
root_node.setPurse(4);
root_node.setParentBid(0);
// root_node.printNode();
queue<node> myQ;
myQ.push(root_node);
/* BFS like creation of perfect information tree */
while(true){
node &ext = myQ.front();
if(D)
cout << "h1" << endl;
if(ext.getLevel() == LEVEL){
break;
}
if(D)
cout << "h2" << endl;
int type = ext.getType();
if(D)
cout << "h3" << endl;
for(int i = 0; i < ext.actions.size() ; i++){
node &child = *(ext.actions[i]);
if(D)
cout << "h4" << endl;
//process(child);
/* set parent */
child.setParent(ext);
if(D)
cout << "h5" << endl;
/* set type & items won so far */
if((ext.getLevel()) % 2 == 0){ // i.e. even numbered level, then current round has ended
if(i > ext.getParentBid()){
child.setType(type);
}
else{
int type_val = ( *(*(ext.getParent()))).getType() ;
child.setType( type_val );
}
}
else{
if(type == 1){
child.setType(2);
}
else{
child.setType(1);
}
}
if(D)
cout << "h6" << endl;
/* set level */
child.setLevel(ext.getLevel() + 1);
if(D)
cout << "h7" << endl;
/* set purse */
if(child.getType() == ext.getType()){
int val = ext.getPurse() - i;
if(val < 0){
child.setPurse(0);
}
else{
child.setPurse(val);
}
}
else{
if( *(ext.getParent()) != NULL ){
int val = ( *(ext.getParent()))->getPurse() - ext.getParentBid();
if(val < 0){
child.setPurse(0);
}
else{
child.setPurse( val );
}
}
else{
child.setPurse(3);
}
}
if(D)
cout << "h8" << endl;
/* set parent bid */
child.setParentBid(i);
if(D)
cout << "h9" << endl;
/* when the child is ready with all its attributes, add it to the queue */
myQ.push(child);
child.printNode();
}
cout << endl << endl << "----Next Set of Children----" << endl;
myQ.pop();
}
return 0;
}
程序在此行child.setPurse( val );
处挂起我相信由以下行计算的值
int val = ( *(ext.getParent()))->getPurse() - ext.getParentBid();
错了。 *(ext.getParent())
指向某个垃圾节点的位置。任何帮助将不胜感激,因为我现在无法解决这个问题超过24小时。谢谢。
答案 0 :(得分:1)
队列正在存储node
类型的对象。您正在使用指针进入队列。你不应该这样做!当您从队列中弹出时,在每次通过主循环结束时执行该操作时,会破坏您的对象。
查找
node &ext = myQ.front();
// etc...
for(int i = 0; i < ext.actions.size() ; i++){
node &child = *(ext.actions[i]);
child.setParent(ext);
// etc...
myQ.push(child);
}
myQ.pop(); // <-- POOF!! Every pointer to 'ext' is now invalid.
每次添加到队列时,都会创建对象的副本。引用该副本时,您正在使用队列的内部副本。最终该副本将不存在。当将指针设置为每个孩子的父母时,你就会遇到严重的麻烦。
这不会更快爆发的唯一原因是因为你在node
中没有提供适当的析构函数来泄漏记忆(以清理actions
)。如果你实现了一个,你还必须实现一个复制构造函数(或者通过创建一个私有的空复制构造函数来防止复制)。
您真正需要做的是更改队列以使用指针:
queue<node*> myQ;
myQ.push(&root_node);
// etc...