分配和删除指针

时间:2011-10-28 15:28:03

标签: c++ memory pointers multidimensional-array

好的,所以这是上下文。我已经连续工作了近一天,正在研究传奇的8-puzzle问题。我有我的启发式算法,我的A_star算法失效了。项目规范要求我们使用三种不同的启发式值来解决它。我可以单独为三个中的任何一个解决它,但是当我连续解决它们时,我得到一个荒谬的循环,它永远找不到正确的继承状态。

相信我的问题在于我的指针。我有一个类,State,如下所定义,它有一个int **数组和一个指向State(它的父类)的指针。

编辑:我必须使用项目规范定义的int **,否则我很乐意使用指针。

State   (int **bd, State* prnt);
State   (const State& other);
~State  ();

然后我就这样声明:

State::State(int **bd, State* prnt) {

// allocate the board
board = new int*[3];
for (int i = 0; i < 3; i++) {
    board[i] = new int[3];
}

// fill in the board
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        board[i][j] = bd[i][j];
        //board[i][j] = 
    }
}

// set the parent
parent = prnt;

}

State::State(const State& other) {
// allocate the board
board = new int*[3];
for (int i = 0; i < 3; i++) {
    board[i] = new int[3];

State::~State() {
//std::cout << "Deconstructing " << this << endl;
for (int i = 0; i < 3; i++)
    delete board[i];
delete [] board;
delete parent;
parent = other.parent;

}

State::~State() {
//std::cout << "Deconstructing " << this << endl;
for (int i = 0; i < 3; i++)
    delete board[i];
delete [] board;
delete parent;

}

State& State::operator=(const State &rhs) {
if (&rhs == this) {
    return *this;
}

for (int i = 0; i < 3; i++) {
    delete board[i];
}
delete [] board;

// allocate the board
board = new int*[3];
for (int i = 0; i < 3; i++) {
    board[i] = new int[3];
}

// fill in the board
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        //board[i][j] = rhs.board[i][j];
        board[i][j] = rhs.getIntAtCoor(j, i);
    }
}

//delete parent;
// set the parent
parent = rhs.parent;

// set g
g = rhs.g;
f = rhs.f;
hType = rhs.hType;

return *this;

}

我没有给出确切的声明 - 其中一些很简单,比如int = int。我只是无法弄明白。我觉得我的删除父错误或我的 parent = other.parent 错误(或两者兼而有之)。

感谢您的时间和帮助,

泰勒

3 个答案:

答案 0 :(得分:2)

升级代码样式可能会导致错误消失。换句话说,newdelete容易出错,应该避免使用更好的替代方案。

对于细胞的管理,请考虑:

  • std::shared_ptr:可用于取消delete来电
  • std::vector可用于避免newdelete来电 请注意,您应该像std::vector<int> board( 3 * 3 )board.at( x + y * 3 )一样使用它。
  • 最重要的是只使用静态数组int board[3][3]。根本没有分配。

儿童州也不拥有父母国家。这是相反的方式。因此,儿童国家不应该删除他们的父母。您仍然可以安全地保留父指针,但在允许父级超出范围(删除或其他)之前,请确保清除子级。所有这些清理和删除都不一定涉及新的。您的State类看起来很小,如果按值复制则无关紧要。在这种情况下,只需让父级使用std::vector<State> m_children,编译器将负责其余的工作。

答案 1 :(得分:1)

您没有显示复制构造函数的完整定义,但我假设parent = other.parent行在那里。在这种情况下,父母不会对其自己的生命负责,并且析构函数中的delete parent根本不存在。

另请注意,您至少需要禁用(私有声明)或实现复制赋值运算符。

更好的是,为{2}数组使用vector vector,让语言为您服务。

答案 2 :(得分:0)

也许不是直接的答案,但是你反对C ++的最佳实践。

使用向量解决此问题更容易,也更容易维护。

size_t row_sz = 3;
size_t col_sz = 3;
std::vector<int> board(row_sz * col_sz, 0);

int i = 0;
for (size_t r = 0; r < 0; r++)
for (size_t c = 0; c < 0; c++)
  board[ r * row_sz + c ] = i++;

使用上述策略也可以更轻松地处理多维数组。它只是打破了。如果你真的想要行/ col访问,请在它周围写一个包装器。

struct Matrix {
  int &operator()(size_t r, size_t c);
  const int &operator()(size_t r, size_t c) const;

private:
  std::vector<int> data;
};