2012-10-23 97 views
0

我正在生成描述两个节点(称为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小时现在。谢谢。

回答

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...