指向垃圾节点的指针

时间:2012-10-23 02:51:59

标签: c++ pointers

我正在生成一个大型游戏树,描绘两个节点之间的拍卖场景(称为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 个答案:

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