C++ 析构函数顺序
我有这样的课程: 游戏: 程序结束时,我在~BordField中发现错误: 引发异常:读取访问冲突。 这是0xFDFDFDFDC++ 析构函数顺序,c++,destructor,object-lifetime,C++,Destructor,Object Lifetime,我有这样的课程: 游戏: 程序结束时,我在~BordField中发现错误: 引发异常:读取访问冲突。 这是0xFDFDFDFD 我把我的析构函数弄错了吗?从多维数组中清除内存的最佳方法是什么 您的设计有两个基本缺陷: 没有明确的BoardField的所有权:有人创建它,有人删除它。如果你非常谨慎,它可以工作,但它很容易出错 您无法确保:如果您有任何代码段,其中您创建了游戏或任何BoardField的副本,则第一个被销毁的对象将删除m_段指针,当第二个对象被销毁时,它将再次尝试删除同一指针,即U
我把我的析构函数弄错了吗?从多维数组中清除内存的最佳方法是什么 您的设计有两个基本缺陷:
- 没有明确的
BoardField的所有权:有人创建它,有人删除它。如果你非常谨慎,它可以工作,但它很容易出错李>
- 您无法确保:如果您有任何代码段,其中您创建了
或任何游戏
的副本,则第一个被销毁的对象将删除BoardField
指针,当第二个对象被销毁时,它将再次尝试删除同一指针,即UB李>m_段
- 您无法确保:如果您有任何代码段,其中您创建了
- 如果m_board_fields是固定大小的2d数组,则将其设置为固定大小数组(也称为
)。如果要使其大小保持动态,请使用向量BoardField*m_board_fields[8][8]
- 如果预期存在某种多态性,则m_board_字段的单元格可以是指针。但这里似乎不是这样,因为显然ChessPiece是多态类。因此最好使用普通字段而不是指针(aka
)李>BoardField m_board_fields[8][8]
- 最后,与其使用原始指针指向
,不如使用棋子
:您不必担心指针的浅拷贝和双重删除;共享的\u ptr
将自行处理,并在不再使用时销毁该对象李>shared_ptr
m_-piece
从未初始化-它包含不确定的值,并且如果您尝试取消引用它(例如,通过使用delete
),您的程序将显示未定义的行为。2) 我们可以看到您创建了一个二维数组m_board_fields
,它存储指向BoardField
的指针。这种数组的内容在哪里初始化?由于析构函数尝试删除这些指针,并且再次取消对未初始化指针的引用是未定义的行为。为什么不使用std::array
和一些辅助函数来实现索引,而不是执行大量堆分配?为什么不使用BoardField m_board_fields[8][8]
?使用std::vector
或std::array
。您正在删除但未分配m_board_字段[i][j]
。还要注意类似(intj=0;i<8;j++)的for
。
class Game {
private:
BoardField*** m_board_fields;
public:
Game() {
m_board_fields = new BoardField**[8];
for (int i = 0; i < 8; i++) {
m_board_fields[i] = new BoardField*[8];
}
}
Game::~Game() {
for (int i = 0; i < 8; i++) {
for (int j = 0; i < 8; j++) {
delete m_board_fields[i][j];
}
delete[] m_board_fields[i];
}
delete[] m_board_fields;
}
}
class BoardField {
private:
ChessPiece* m_piece;
....
public:
BoardField::~BoardField() {
delete m_piece;
}
}