connect4 malloc 错误的复制构造函数
Copy constructor for connect4 malloc errors
我正在尝试编写一个 minimax 算法来解决 connect 4 与 alpha-beta 修剪。我什么都做不到,因为我无法复制游戏板...
默认构造函数:
gameStatus::gameStatus(){
13 gameData = new long[42];
14 gameBoard[0] = &(gameData[0]);
15 gameBoard[1] = &(gameData[7]);
16 gameBoard[2] = &(gameData[14]);
17 gameBoard[3] = &(gameData[21]);
18 gameBoard[4] = &(gameData[28]);
19 gameBoard[5] = &(gameData[35]);
20
21 int i;
22 for (i = 0; i < 42; i++)
23 {
24 gameData[i] = 0;
25 }
26
27 currentTurn = 1;
28 player1Score = 0;
29 player2Score = 0;
30 pieceCount = 0;
31 gameFile = 0;
32 utilityValue = 0;
33 }
我的复制构造函数如下:(我尝试在每一个之前使用 'this->',也尝试将第 21/22 行组合成 gameData = g.gameData)
21 gameStatus(const gameStatus &g){
22 gameData = new long[42];
23 gameData = g.gameData;
24 gameBoard[0] = &(g.gameData[0]);
25 gameBoard[1] = &(g.gameData[7]);
26 gameBoard[2] = &(g.gameData[14]);
27 gameBoard[3] = &(g.gameData[21]);
28 gameBoard[4] = &(g.gameData[28]);
29 gameBoard[5] = &(g.gameData[35]);
30 currentTurn = g.currentTurn;
31 player1Score = g.player1Score;
32 player2Score = g.player2Score;
33 pieceCount = g.pieceCount;
34 gameFile = g.gameFile;
35 utilityValue = g.utilityValue;
36 }
无论我尝试什么,如果我在 aiPlay 函数中包含此调用:
429 gameStatus tmpGame(currentGame);
事情是这样的。我的举动:
MaxConnect-4 game
Current Board:
-----------------
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 0 1 0 0 |
-----------------
CPU移动:
MaxConnect-4 game
Current Board:
-----------------
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 2 1 0 10414574138294272 |
-----------------
然后在下一个 CPU 移动中我得到了这个:
malloc:对象 0x7fe521402b50 的 *** 错误:未分配正在释放的指针
您有内存泄漏和错误共享。
gameStatus(const gameStatus &g){
gameData = new long[42];
gameData = g.gameData;
这里,你请求了42long
s,接收到一个指向新分配数据的指针,并将其存储在gameData
中。当你用 g
的数据地址覆盖它时,你负责 delete[]
ing 的这个指针立即 丢失,在行 gameData = g.gameData
。请记住,复制指针是浅拷贝,而不是深拷贝。在像 gameStatus g2 = g1;
这样的副本之后,两个 游戏将指向相同的 gameData
,导致双重删除和可怕的错误。
要解决此问题,请删除行 gameData = g.gameData;
,然后遍历 gameData
的条目,将每个 g.gameData[i]
分配给 gameData[i]
,这将是一个很深的问题复制.
for (int i = 0; i < 42; ++i){
gameData[i] = g.gameData[i];
}
gameBoard[0] = &(g.gameData[0]);
gameBoard[1] = &(g.gameData[7]);
gameBoard[2] = &(g.gameData[14]);
gameBoard[3] = &(g.gameData[21]);
gameBoard[4] = &(g.gameData[28]);
gameBoard[5] = &(g.gameData[35]);
在这里,您将 gameBoard
的条目(我假设它用于方便的数组索引;我无法从您显示的内容中分辨出来)指向 other 游戏的数据,不是你自己的数据。您可能想指向自己的数据。
gameBoard[0] = &(gameData[0]); // or equivalently, gameData
gameBoard[1] = &(gameData[7]); // or equivalently, gameData + 7
gameBoard[2] = &(gameData[14]);
gameBoard[3] = &(gameData[21]);
gameBoard[4] = &(gameData[28]);
gameBoard[5] = &(gameData[35]);
currentTurn = g.currentTurn;
player1Score = g.player1Score;
player2Score = g.player2Score;
pieceCount = g.pieceCount;
gameFile = g.gameFile;
utilityValue = g.utilityValue;
}
构造函数的其余部分乍一看还不错,但我不能确定。您需要提供所有这些 class 成员的定义才能确定。但假设其中 none 个是原始指针,这应该可以正常工作。
我假设您实现了一个删除数组 gameData
.
的析构函数
您正在从您复制的内容中窃取内存。这对于移动构造函数来说可能没问题,但对于复制构造函数来说就不行了。
gameStatus(const gameStatus &g) {
gameData = new long[42]; // leaked memory
// g.gameData will be destroyed
// this->gameData will be equal to a deleted resource
gameData = g.gameData;
gameBoard[0] = &(g.gameData[0]);
// ...
}
你要的是复制值:
gameStatus(const gameStatus &g) {
gameData = new long[42]; // not leaked
std::copy(g.gameData, g.gameData + 42, gameData);
gameBoard[0] = &(gameData[0]);
// ...
}
这将一个一个地复制值。
我正在尝试编写一个 minimax 算法来解决 connect 4 与 alpha-beta 修剪。我什么都做不到,因为我无法复制游戏板...
默认构造函数:
gameStatus::gameStatus(){
13 gameData = new long[42];
14 gameBoard[0] = &(gameData[0]);
15 gameBoard[1] = &(gameData[7]);
16 gameBoard[2] = &(gameData[14]);
17 gameBoard[3] = &(gameData[21]);
18 gameBoard[4] = &(gameData[28]);
19 gameBoard[5] = &(gameData[35]);
20
21 int i;
22 for (i = 0; i < 42; i++)
23 {
24 gameData[i] = 0;
25 }
26
27 currentTurn = 1;
28 player1Score = 0;
29 player2Score = 0;
30 pieceCount = 0;
31 gameFile = 0;
32 utilityValue = 0;
33 }
我的复制构造函数如下:(我尝试在每一个之前使用 'this->',也尝试将第 21/22 行组合成 gameData = g.gameData)
21 gameStatus(const gameStatus &g){
22 gameData = new long[42];
23 gameData = g.gameData;
24 gameBoard[0] = &(g.gameData[0]);
25 gameBoard[1] = &(g.gameData[7]);
26 gameBoard[2] = &(g.gameData[14]);
27 gameBoard[3] = &(g.gameData[21]);
28 gameBoard[4] = &(g.gameData[28]);
29 gameBoard[5] = &(g.gameData[35]);
30 currentTurn = g.currentTurn;
31 player1Score = g.player1Score;
32 player2Score = g.player2Score;
33 pieceCount = g.pieceCount;
34 gameFile = g.gameFile;
35 utilityValue = g.utilityValue;
36 }
无论我尝试什么,如果我在 aiPlay 函数中包含此调用:
429 gameStatus tmpGame(currentGame);
事情是这样的。我的举动:
MaxConnect-4 game
Current Board:
-----------------
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 0 1 0 0 |
-----------------
CPU移动:
MaxConnect-4 game
Current Board:
-----------------
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 |
| 0 0 0 2 1 0 10414574138294272 |
-----------------
然后在下一个 CPU 移动中我得到了这个:
malloc:对象 0x7fe521402b50 的 *** 错误:未分配正在释放的指针
您有内存泄漏和错误共享。
gameStatus(const gameStatus &g){
gameData = new long[42];
gameData = g.gameData;
这里,你请求了42long
s,接收到一个指向新分配数据的指针,并将其存储在gameData
中。当你用 g
的数据地址覆盖它时,你负责 delete[]
ing 的这个指针立即 丢失,在行 gameData = g.gameData
。请记住,复制指针是浅拷贝,而不是深拷贝。在像 gameStatus g2 = g1;
这样的副本之后,两个 游戏将指向相同的 gameData
,导致双重删除和可怕的错误。
要解决此问题,请删除行 gameData = g.gameData;
,然后遍历 gameData
的条目,将每个 g.gameData[i]
分配给 gameData[i]
,这将是一个很深的问题复制.
for (int i = 0; i < 42; ++i){
gameData[i] = g.gameData[i];
}
gameBoard[0] = &(g.gameData[0]);
gameBoard[1] = &(g.gameData[7]);
gameBoard[2] = &(g.gameData[14]);
gameBoard[3] = &(g.gameData[21]);
gameBoard[4] = &(g.gameData[28]);
gameBoard[5] = &(g.gameData[35]);
在这里,您将 gameBoard
的条目(我假设它用于方便的数组索引;我无法从您显示的内容中分辨出来)指向 other 游戏的数据,不是你自己的数据。您可能想指向自己的数据。
gameBoard[0] = &(gameData[0]); // or equivalently, gameData
gameBoard[1] = &(gameData[7]); // or equivalently, gameData + 7
gameBoard[2] = &(gameData[14]);
gameBoard[3] = &(gameData[21]);
gameBoard[4] = &(gameData[28]);
gameBoard[5] = &(gameData[35]);
currentTurn = g.currentTurn;
player1Score = g.player1Score;
player2Score = g.player2Score;
pieceCount = g.pieceCount;
gameFile = g.gameFile;
utilityValue = g.utilityValue;
}
构造函数的其余部分乍一看还不错,但我不能确定。您需要提供所有这些 class 成员的定义才能确定。但假设其中 none 个是原始指针,这应该可以正常工作。
我假设您实现了一个删除数组 gameData
.
您正在从您复制的内容中窃取内存。这对于移动构造函数来说可能没问题,但对于复制构造函数来说就不行了。
gameStatus(const gameStatus &g) {
gameData = new long[42]; // leaked memory
// g.gameData will be destroyed
// this->gameData will be equal to a deleted resource
gameData = g.gameData;
gameBoard[0] = &(g.gameData[0]);
// ...
}
你要的是复制值:
gameStatus(const gameStatus &g) {
gameData = new long[42]; // not leaked
std::copy(g.gameData, g.gameData + 42, gameData);
gameBoard[0] = &(gameData[0]);
// ...
}
这将一个一个地复制值。