简体   繁体   English

如何在C ++中解除分配?

[英]How do I deallocate this in C++?

I create a 2D array of Nodes ( Node class is in a separate file) and i'm wondering how to deallocate exactly this (below). 我创建了一个Nodes的二维数组( Node类在一个单独的文件中),我想知道如何解除分配(下图)。 I've tried many ways and mem leaks still appear. 我尝试了很多方法,但仍然会出现漏洞。

board = new Node * [r];

//creats a column for each element in the row
for(int i = 0; i < r; i++) {
    board [i] = new Node [c];
}

( r is the rows and c is the cols) r是行, c是cols)

I've done this: 我这样做了:

for(int i = 0; i < r; i++) {

    delete [] board[i];
}

delete [] board;

But apparently it's not enough 但显然这还不够

The code you have is correct and sufficient. 您拥有的代码是正确和充分的。 However, it would be better to use RAII so that you do not need to explicitly call delete at all (perhaps not even new ). 但是,使用RAII会更好,因此您根本不需要显式调用delete (可能甚至不是new )。 For example, you could create a std::vector<std::vector<Node>> , or better still, some sort of matrix class (not in the standard library, unfortunately). 例如,您可以创建一个std::vector<std::vector<Node>> ,或者更好的是,某种矩阵类(不幸的是,不在标准库中)。

Your solution is the correct way to free two dimensional array. 您的解决方案是释放二维数组的正确方法。 However you may still get a memory leak if Node uses dynamic memory and it's destructor is not properly defined. 但是,如果Node使用动态内存并且未正确定义析构函数,则可能仍会出现内存泄漏。

As others have said, you're correctly pairing up all your new[] s and delete[] s: assuming no errors occur, the memory allocated by this code will be correctly deallocated. 正如其他人所说,你正确配对你所有的new[]delete[] s:假设没有错误发生,这个代码分配的内存将被正确释放。

The only issue is that errors may occur, and in particular exceptions may be thrown: 唯一的问题是可能会发生错误,特别是可能会抛出异常:

  • new[] can throw an exception if it fails to allocate memory (doesn't normally happen on desktop OSes, but you should still write code as if it does.) new[]如果无法分配内存,则会抛出异常(通常不会在桌面操作系统上发生,但您仍应该像编写代码一样编写代码。)
  • Node 's constructor may throw. Node的构造函数可能会抛出。 Even if you've designed the constructor not to throw you generally shouldn't take advantage of that knowledge. 即使你设计的构造函数不是扔你一般不应该利用这些知识。 Just write code as if throws. 只需编写代码就像抛出一样。
  • In fact, you should just generally write code as if pretty much anything can throw. 事实上,你应该只是编写代码,好像几乎任何东西都可以抛出。 For more detailed info on writing exception safe code, and on what the exceptions to this rule are you can read the info at http://exceptionsafecode.com 有关编写异常安全代码的更多详细信息,以及此规则的例外情况,您可以在http://exceptionsafecode.com上阅读该信息。

The best way to make this code exception safe is to use RAII. 使此代码异常安全的最佳方法是使用RAII。 For example use a vector instead of new[] / delete[] . 例如,使用vector而不是new[] / delete[]


Using an array of pointers and a separate allocation for each row makes sense for 'ragged' arrays, where each row can be a different length. 使用指针数组和每行的单独分配对于“粗糙”数组是有意义的,其中每行可以是不同的长度。 In your case you have rectangular array, so you can use a single allocation for the whole thing. 在你的情况下,你有矩形数组,所以你可以使用单个分配整个事情。

std::vector<Node> board(rows*columns);

board[row_index*columns + column_index] // replaces board[row_index][column_index]

You can hide the implementation by putting this in a class: 您可以通过将其放在类中来隐藏实现:

class Board {
  std::vector<Node> board_data;
public:
  const int rows;
  const int columns;

  Board(int rows_, int columns_)
    : board_data(rows_*columns_)
    , rows(rows_)
    , columns(columns_)
  {}

  struct board_index { int row, column; };

  Node &operator[](board_index i) {
    assert(0 <= i.row && i.row < rows);
    assert(0 <= i.column && i.column < columns);
    return board_data[i.row * columns + i.column];
  }
};

Board board(r, c);

with the above implementation you replace board[i][j] with board[{i, j}] . 使用上面的实现,你将board[i][j]替换为board[{i, j}]

board[{i, j}] = ... // assign to a place on the board
board[{i, j}].foo(); // call a Node method
std::cout << board[{i, j}]; // print a Node
// etc.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM