- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有这个类 ChessBoard,这是它的标题:
class ChessBoard
{
Field** board;
Color currentColor;
public:
ChessBoard();
ChessBoard(const ChessBoard&);
Field* findField(std::string);
ChessBoard& operator = (const ChessBoard&);
bool checkIfFieldHasFigure(std::string);
void writeOneState(SahApi*);
void playAllMoves(std::istream*, SahApi*);
void playMove(std::string);
~ChessBoard();
};
我有它的构造函数,它创建了棋盘的开始阶段:(非常可怕,我知道 :) )
ChessBoard::ChessBoard()
{
int i, j;
Error err;
board = new Field*[8];
if(!board)
{
err.writeToOutput(1);
exit(1);
}
for(i = 0; i < 8; i++)
{
board[i] = new Field[8];
if(!board[i])
{
err.writeToOutput(1);
exit(1);
}
}
currentColor = WHITE;
char c;
std::string s;
Figure f;
for(i = 0; i < 8; i++)
for(j = 0; j < 8; j++)
{
s.clear();
c = i + 'A';
s.push_back(c);
c = j + '1';
s.push_back(c);
board[i][j].position.assign(s);
if((j > 1) && (j < 6))
board[i][j].hasFigure = 0;
else board[i][j].hasFigure = 1;
if((i+j+2) % 2)
board[i][j].color = WHITE;
else board[i][j].color = BLACK;
if( ((j==0)||(j==7)) && ((i==0)||(i==7)) )
{
Rook* r = new Rook(((j==0)?WHITE:BLACK), s);
if(!r)
{
err.writeToOutput(1);
exit(1);
}
board[i][j].putFigure(r);
}
else if( ((i==1)||(i==6)) && ((j==0)||(j==7)) )
{
Knight* n = new Knight(((j==0)?WHITE:BLACK), s);
if(!n)
{
err.writeToOutput(1);
exit(1);
}
board[i][j].putFigure(n);
}
else if( ((i==2)||(i==5)) && ((j==0)||(j==7)) )
{
Bishop* b = new Bishop(((j==0)?WHITE:BLACK), s);
if(!b)
{
err.writeToOutput(1);
exit(1);
}
board[i][j].putFigure(b);
}
else if( (i==3) && ((j==0)||(j==7)))
{
Queen* q = new Queen(((j==0)?WHITE:BLACK), s);
if(!q)
{
err.writeToOutput(1);
exit(1);
}
board[i][j].putFigure(q);
}
else if( (i==4) && ((j==0)||(j==7)) )
{
King* k = new King(((j==0)?WHITE:BLACK), s);
if(!k)
{
err.writeToOutput(1);
exit(1);
}
board[i][j].putFigure(k);
}
else if( (j==1) || (j==6) )
{
Pawn* p = new Pawn(((j==1)?WHITE:BLACK), s);
if(!p)
{
err.writeToOutput(1);
exit(1);
}
board[i][j].putFigure(p);
}
}
}
我还需要一个 ChessBoard 的析构函数,它是这样的:
ChessBoard::~ChessBoard()
{
//for(int i = 0; i < 8; i++)
// delete board[i];
delete [] board;
}
部分被注释掉的原因是我的第一个问题:
<强>1。为什么我不能用上面写的方法删除我所有的字段? 当我尝试这样做时,程序进入“ block 类型有效”错误,我知道这是由于试图删除不存在的内存引起的。当我将其注释掉时,该程序运行良好。 ChessBoard 是一个 8x8 矩阵,所以我应该可以像我在这里尝试的那样删除它。
我的第二个问题是:
<强>2。如何删除我的棋盘构造函数中存在的指向数字(国王、王后、车等)的指针?这很令人困惑,因为这些指针用作我的棋盘的一部分,而我使用它们直到节目结束。当程序结束时,我需要释放内存,但我不知道如何访问这些指针。数字本身会被自动删除,因为它们都是非指针。 我什至需要删除那些指针,因为我使用它们直到最后,然后所有内容都被释放了吗?
最佳答案
新建/删除的一般规则是调用必须相互匹配。你用
创建你的板board = new Field*[8];
for(i = 0; i < 8; i++)
{
board[i] = new Field[8];
}
您将需要以相同的方式删除您的看板,但要倒退:
for(i = 0; i < 8; i++)
{
delete [] board[i];
}
delete[] board;
由于这不起作用,我猜您的问题是双重删除。其他东西正在释放阵列。您是否有指向同一个 Field** 的 ChessBoard 拷贝?
您将不得不以类似的方式删除您的图形。
for (int x = 0; x < 8; x ++)
for (int y = 0; y < 8 ;y ++)
if (board[y][x] != NULL)
delete board[y][x];
只要您从板上删除图形的代码删除了该图形并将该图形的位置设置为 NULL,此代码就可以工作。
2b。你的 2 问题的第二部分是你是否必须完全删除任何内容,因为程序正在结束。你是对的,因为如果你要立即退出,你不需要删除任何东西,操作系统无论如何都会为你释放所有内存。
不过,您通常应该这样做,通常您最终会通过允许它们运行多次来修改大多数程序,然后您将发生内存泄漏,因为每次运行都会使用更多的内存。
这就是如何解决你的问题。但是,我强烈建议您更改大部分代码的样式并删除所有动态分配。
首先,使用常规静态大小的数组 (Field[8][8]) 来存储字段。我的意思是,棋盘何时会改变大小?
其次,按值存储片段。如果片段在某个位置,您的字段类已经存储。还让 Field 类存储一个代表类型的枚举。没有理由为您的作品使用动态分配。
第三,不需要检查new
的返回是否为NULL。如果有错误,它将抛出异常,您的程序将停止(因为它应该,当您内存不足时您无能为力)。
关于c++ - 析构函数和指向类属性的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8548905/
有人能给我解释一下我下面程序中的一点吗我编写的以下程序是为了理解 int * const * var 的含义; #include "iostream" using namespace std ; in
我正在摆弄 C 中的指针,但仍然不确定一些非常基础的知识。我想出了以下示例代码: #include int main(void) { int num = 42; /
以下代码产生警告: const char * mystr = "\r\nHello"; void send_str(char * str); void main(void){ send_str
我正在尝试在我的 Linux 计算机上升级 cmake。这是我使用的命令。 删除旧的 cmake: sudo apt purge --auto-remove cmake 从 https://cmake
我试图借助 char 指针来追踪 union 第一个字节的值。我假设 byte1 的输出应该是 ff,但实际上是 ffffffff。如果我错了请纠正我。 #include #include #in
我正在使用微 Controller 进行一些 ADC 测量。当我尝试使用 -O2 优化编译以下代码时遇到问题,当代码中存在 PrintVal() 函数时,MCU 卡住。我做了一些调试,结果发现,当我添
#include #include using namespace std; int main () { vector qwerty; qwerty.push_back(5);
我有我的 woking setup.py 文件;其中包含以下行: home = os.environ["HOME"] # home = /home/dr in my machine; distu
这段代码 #include #include static_assert(std::is_same_v::value_type, volatile int>); 在最新的 GCC 和 clang
我对 C 中的前向声明有疑问。 代码 typedef struct yhash_s t_yhash;// forward declaration struct yhash_s { size_t
我想提取成员指针指向的成员的类型。 template void demo(myClass& instance, void* ptr) { instance.*member = *reinter
我正在尝试使用指针将一段 C 代码转换为 Swift 3。这是 C 代码中的相关部分。 Float32 sampleArray[256] = { // Array is 256 Float value
您可能知道,VLA's haves pros and cons 和它们在 C11 中是可选的。 我想使 VLA 成为可选项的主要原因是:“堆栈可能会爆炸”: int arr[n]; /* where
这段代码有什么错误?为什么我不能按照我尝试的方式取消引用该元素。 #include typedef struct { int value; struct node * left;
有什么方法可以在 JavaScript 中创建\返回指向变量的指针吗? 比如,在 PHP 中: function func() { ..... return &$result; } 我
如果您想使用方法的指针作为参数,则需要将该方法键入作为对象的函数,就像这样好 : type TAcceptor = function(filename:string):boolean of objec
很简单的问题: 我对 C++ 中的智能指针有点陌生。我想我得到了所有权的东西,但我不知道如何访问他们实际指向的内容。当我尝试使用对象的成员函数/变量时,我只是得到了 unique_ptr 类的函数,这
我得到了一个点的方位 Angular 、指南针方向和一个可以将箭头设置到某个方向的 api(0 是顶部,90 是右侧,180 是底部,360 是顶部) 如果我希望箭头指向我采用方位 Angular 形
我正在尝试找到一种方法,从单元格中获取位于当前工作表左侧(托盘下方)的工作表单元格中的数据。 我知道如何通过调用其他工作表 =Sheet1!A1 但现在我需要一些最好的解释 =Sheet[-1]!A1
所以我在 MATLAB 中有一个 for 循环,其中向量 x 将通过一个函数,比如 cos(x).^2,或者不同的选择,比如 sin(x).^2 + 9.*x。用户将在 for 循环之前选择他想使用的
我是一名优秀的程序员,十分优秀!