简体   繁体   English

C ++中的内存分配失败(使用new和delete)

[英]Memory Allocation Failure in C++(using new & delete)

I am an ordinary student trying to code a Monte-Carlo Tree Search. 我是一名普通学生,试图编写蒙特卡洛树搜索代码。

To do this, I made a struct named "Node", and tried to make new Node* pointers and allocate memory to them with "new", but my program keeps on crashing, and I would reeeeally appreciate some help. 为此,我创建了一个名为“ Node”的结构,并尝试创建新的Node *指针并使用“ new”为它们分配内存,但是我的程序不断崩溃,因此我非常感谢您的帮助。

Here's what my code looks like. 这是我的代码的样子。 Locations of failure are marked. 标记故障位置。

Thank you in advance. 先感谢您。

Node* knell;
Node* treePolicy(Node* currentnode){
    puts("treepolicy");
    Node* temp=(Node*)malloc(sizeof(Node));
    puts("Mem Allocated");
    Move save=MCTBoard.generateRandomLegalMove(currentnode->player);      ///works very well up to here.
    save.printMove();
    temp=findNode(currentnode,save);
    puts("Node Found");
    knell=new Node; 
    if(temp==NULL){
        free(temp);
        temp = new Node; ///crashes the second time treePolicy(Node*) is called.
        temp->setMove(save);
        temp->child.clear();
        currentnode->child.push_back(temp);
        temp->parent=currentnode;
        MCTBoard.playMove(save,currentnode->player);
        for(int i=0;i<4;i++){
            for(int j=0;j<=i;j++){
                for(int k=0;k<=i;k++){
                    temp->board[i][j][k]=MCTBoard.a[i][j][k];
                }
            }
        }
        temp->value=temp->visited=temp->win=temp->draw=0;
        temp->player=3-currentnode->player;
        knell=temp;
        //delete temp; -> even with this enabled, still crashes.
        return knell;///an infinite loop happens here, but that is another problem so...
    }
else{
    ///not important,and besides,I've not even reached here yet once.
}

} }

actually there does exist a same problem in another function, but I feel that that is some other problem. 实际上在另一个函数中确实存在相同的问题,但是我认为那是另一个问题。

So, can anyone please tell me why it crashes?? 所以,谁能告诉我为什么它崩溃了?

Let's walk through the life cycle of temp . 让我们来看一下temp的生命周期。

You allocated memory using malloc . 您使用malloc分配了内存。

Node* temp=(Node*)malloc(sizeof(Node));

and then you are overriding the temp by return value of below function. 然后通过下面的函数的返回值覆盖temp

temp = findNode(currentnode,save);

then you are deleting it using free . 那么您将使用free删除它。

free(temp);

Memory above which you are freeing using free is returned from findNode . findNode返回您在上面使用free释放的内存。 Most probably reason for the crash is that function returned memory allocated using new rather than malloc . 崩溃的原因很可能是该函数返回了使用new而不是malloc分配的malloc

A couple of comments: 几点评论:

Node* knell;

why make knell a global variable? 为什么要使knell成为全局变量? Why not handle the assignment of the global outside of the function (perhaps something that looks like: 为什么不处理函数外部的全局赋值(也许看起来像这样:

knell = treePolicy(currentNode);

) or something similar )或类似的内容

Node* treePolicy(Node* currentnode){
    puts("treepolicy");
    Node* temp=(Node*)malloc(sizeof(Node));

No reason to malloc here. 没有理由在这里分配。 You're going to overwrite later, so lets remove this line. 您稍后将要覆盖,因此请删除此行。

    puts("Mem Allocated");
    Move save=MCTBoard.generateRandomLegalMove(currentnode->player);      ///works very well up to here.
    save.printMove();
    temp=findNode(currentnode,save);

Here's a great place for auto. 这是汽车的好地方。

    puts("Node Found");
    knell=new Node; 

Like we said above, remove this. 就像我们上面说的,删除它。

    if(temp==NULL){

good place for nullptr nullptr的好地方

        free(temp);

we just determined temp was null. 我们只是确定temp为空。 No need to free 不需要免费

        temp = new Node; ///crashes the second time treePolicy(Node*) is called.
        temp->setMove(save);
        temp->child.clear();
        currentnode->child.push_back(temp);
        temp->parent=currentnode;
        MCTBoard.playMove(save,currentnode->player);
        for(int i=0;i<4;i++){
            for(int j=0;j<=i;j++){
                for(int k=0;k<=i;k++){
                    temp->board[i][j][k]=MCTBoard.a[i][j][k];
                }
            }
        }
        temp->value=temp->visited=temp->win=temp->draw=0;
        temp->player=3-currentnode->player;
        knell=temp;

Let's get rid of this 让我们摆脱这个

        //delete temp; -> even with this enabled, still crashes.
        return knell;///an infinite loop happens here, but that is another problem so...

Ok, so now there's no reason to return knell , but just return temp . 好的,所以现在没有理由返回knell ,而只需返回temp

    }
else{
    ///not important,and besides,I've not even reached here yet once.
}

So the fixed up code should look like: 因此,固定的代码应如下所示:

   Node* treePolicy(Node* currentnode){
        puts("treepolicy");
        Move save=MCTBoard.generateRandomLegalMove(currentnode->player);      ///works very well up to here.
        save.printMove();
        auto temp=findNode(currentnode,save);
        puts("Node Found");
        if(temp==nullptr){
            temp = new Node; ///crashes the second time treePolicy(Node*) is called.
            temp->setMove(save);
            temp->child.clear();
            currentnode->child.push_back(temp);
            temp->parent=currentnode;
            MCTBoard.playMove(save,currentnode->player);
            for(int i=0;i<4;i++){
                for(int j=0;j<=i;j++){
                    for(int k=0;k<=i;k++){
                        temp->board[i][j][k]=MCTBoard.a[i][j][k];
                    }
                }
            }
            temp->value=temp->visited=temp->win=temp->draw=0;
            temp->player=3-currentnode->player;
            return temp;
        }
    else{
        ///not important,and besides,I've not even reached here yet once.
    }

Or something to that effect. 或类似的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM