微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何重新分配三重指针

如何解决如何重新分配三重指针

我目前正在为用C ++实现的tictactoe的ai进行开发,目前我的进展正在进行中。在我的代码中,我有一个看起来像这样的结构。

struct Board {
    int config[3][3];
    Board ** nextboards;
};

我将nextboards设为了双指针,因为我想动态地将一个木板分配给未知数目的木板。使用指针数组将使我的存储不动态。为了增加可能的动作,我做了一个功能

void addPossibleMoves(Board *** board,bool xplayer) {
    
    Board * newboard = (Board *)malloc(sizeof(Board));
    Board * another = (Board *)malloc(sizeof(Board));
    
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            newboard -> config[i][j] = compare[i][j];
        }
    }
    
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            another -> config[i][j] = compare[i][j];
        }
    }

    Board ***temp = (Board ***)realloc(board,2*sizeof(Board));
    temp = board; 
    **board = newboard;
    printBoard( **board);
}

在此函数中,我通过引用传入双指针以操纵内部数据。我的目的是为**board重新分配两倍的大小,并插入两个节点以测试其是否有效。但是,当代码运行realloc函数时,它将暂停并返回不为零的值。有人可以告诉我我在做什么错。

这是我的主要功能

int main() {

   bool xplayer = true;
   Board * startboard = (Board *)malloc(sizeof(Board));

   for (int i = 0; i < 3; i++) {
       for (int j = 0; j < 3; j++) {
           startboard -> config[i][j] = compare[i][j];
       }
   }
   startboard -> nextboards = (Board **)malloc(sizeof(Board));

   addPossibleMoves( & startboard -> nextboards,xplayer);
   printBoard( *(startboard -> nextboards));
}

我目前正在使用devc ++作为我的助手。

解决方法

我按照我认为的样子重写了您的代码。我完全保留了您应该执行什么代码的逻辑。另外,我还保留了您的malloc / realloc / free低级别的内存处理方式。我的代码仍然具有此三重指针***,向您展示如何使用它。另外,在使用free分配之后,您忘记了malloc的所有内存,您应该始终释放分配的那些指针!

在真正的C ++代码中,您应该使用new / delete / delete[]而不是malloc / free。我认为,甚至使用new / delete都不是一个好习惯,最好使用那些已经为您完成所有内存管理的结构,例如std::vector,请参阅第二篇。这样的示例的解决方案,与其保留普通指针并手动删除它们,不如使用std::shared_ptr之类的智能指针。

下面的

第一个代码基本上是您的代码,但有所改进。

Try it online!

#include <cstdlib>
#include <cstdio>

struct Board {
    int config[3][3];
    Board ** nextboards;
};

void freeNextBoards(Board ** nextboards) {
    Board ** cur = nextboards;
    while (*cur) {
        freeNextBoards((*cur)->nextboards);
        ++cur;
    }
    nextboards[0] = 0;
}

void freeBoard(Board * board) {
    freeNextBoards(board->nextboards);
}

void resizeNextBoards(Board *** pnextboards,int cnt) {
    *pnextboards = (Board **)realloc(*pnextboards,cnt * sizeof(Board*));
}

Board * createBoard() {
    Board * board = (Board *)malloc(sizeof(Board));
    board->nextboards = (Board **)malloc(1 * sizeof(Board*));
    board->nextboards[0] = 0;
    return board;
}

void printRepStr(char const * s,int cnt = 1) {
    for (int j = 0; j < cnt; ++j)
        printf("%s",s);
}

void printBoard(Board * board,int indent = 0) {
    for (int i = 0; i < 3; ++i) {
        printRepStr(" ",indent);
        for (int j = 0; j < 3; ++j)
            printf("%02d ",board->config[i][j]);
        printf("\n");
    }
    
    printRepStr(" ",indent);
    printRepStr("-",3 * 3 - 1);
    printf("\n");
    
    Board ** cur = board->nextboards;
    while (*cur) {
        printBoard(*cur,indent + 4);
        ++cur;
    }
}

void addPossibleMoves(Board *** pnextboards,bool xplayer) {
    Board * newboard = createBoard();
    Board * another = createBoard();

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            newboard->config[i][j] = 2 * (i + j); // compare[i][j];
        }
    }

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            another->config[i][j] = 3 * (i + j); // compare[i][j];
        }
    }

    freeNextBoards(*pnextboards);
    resizeNextBoards(pnextboards,3);
    
    (*pnextboards)[0] = newboard;
    (*pnextboards)[1] = another;
    (*pnextboards)[2] = 0;
}

int main() {
    bool xplayer = true;
    Board * startboard = createBoard();

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            startboard->config[i][j] = 1 * (i + j); // compare[i][j];
        }
    }

    addPossibleMoves(&startboard->nextboards,xplayer);
    addPossibleMoves(&startboard->nextboards[0]->nextboards,xplayer);
    printBoard(startboard);
    freeBoard(startboard);

    return 0;
}

输出:

00 01 02 
01 02 03 
02 03 04 
--------
    00 02 04 
    02 04 06 
    04 06 08 
    --------
        00 02 04 
        02 04 06 
        04 06 08 
        --------
        00 03 06 
        03 06 09 
        06 09 12 
        --------
    00 03 06 
    03 06 09 
    06 09 12 
    --------
下面的

第二个代码是第一个代码的改进版本,现在代替了我使用std::vector自动管理内存的所有地方的指针,我使用的config的普通2D数组std::array,为了将文本输出到控制台,我使用了std::cout,也为了捕获异常,我使用了try / catchstd::exception

您可以看到,在下面的基于矢量的代码中,您根本不需要使用malloc / realloc / free做任何工作,因为您始终会忘记释放分配后,一切都会在vector的代码内自动完成。

Try it online!

#include <cstdlib>
#include <cstdio>
#include <vector>
#include <array>
#include <stdexcept>
#include <iostream>
#include <iomanip>
using namespace std;

struct Board {
    array<array<int,3>,3> config = {};
    vector<Board> nextboards;
};

void printRepStr(char const * s,size_t cnt = 1) {
    for (size_t j = 0; j < cnt; ++j)
        cout << s;
}

void printBoard(Board const & board,size_t indent = 0) {
    for (size_t i = 0; i < board.config.size(); ++i) {
        printRepStr(" ",indent);
        for (int j = 0; j < board.config[i].size(); ++j)
            cout << setfill(' ') << setw(2) << board.config[i][j] << " ";
        cout << endl;
    }
    
    printRepStr(" ",board.config[0].size() * 3 - 1);
    cout << endl;

    for (auto const & cur: board.nextboards)
        printBoard(cur,indent + 4);
}

void addPossibleMoves(vector<Board> & pnextboards,bool xplayer) {
    Board newboard,another;

    for (size_t i = 0; i < newboard.config.size(); ++i)
        for (int j = 0; j < newboard.config[i].size(); ++j)
            newboard.config[i][j] = 2 * (i + j); // compare[i][j];

    for (size_t i = 0; i < another.config.size(); ++i)
        for (int j = 0; j < another.config[i].size(); ++j)
            another.config[i][j] = 3 * (i + j); // compare[i][j];

    pnextboards.resize(2);
    
    pnextboards[0] = newboard;
    pnextboards[1] = another;
}

int main() {
    try {
        bool xplayer = true;
        Board startboard;

        for (size_t i = 0; i < startboard.config.size(); ++i)
            for (size_t j = 0; j < startboard.config[i].size(); ++j)
                startboard.config[i][j] = 1 * (i + j); // compare[i][j];

        addPossibleMoves(startboard.nextboards,xplayer);
        addPossibleMoves(startboard.nextboards[0].nextboards,xplayer);
        printBoard(startboard);

        return 0;
    } catch (exception const & ex) {
        cout << "Exception: " << ex.what() << endl;
    } catch (...) {
        cout << "Unknown Exception!" << endl;
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。