0

当我使用 分配多维数组new时,我是这样做的:

void manipulateArray(unsigned nrows, unsigned ncols[])
{
  typedef Fred* FredPtr;
  FredPtr* matrix = new FredPtr[nrows];

  for (unsigned i = 0; i < nrows; ++i)
    matrix[i] = new Fred[ ncols[i] ];

}

其中ncols[]包含 中每个元素的长度matrix,以及nrows中元素的数量matrix

如果我想填充matrix,那么我有

  for (unsigned i = 0; i < nrows; ++i) {
      for (unsigned j = 0; j < ncols[i]; ++j) {
        someFunction( matrix[i][j] );

但我正在阅读C++ FAQ,谁说要非常小心。我应该先初始化每一行NULL。然后,我应该trycatch为行分配。我真的不明白为什么这一切。我一直(但我刚开始)使用上面的代码以 C 风格初始化。

常见问题解答要我这样做

void manipulateArray(unsigned nrows, unsigned ncols[])
{
  typedef Fred* FredPtr;

  FredPtr* matrix = new FredPtr[nrows];

  for (unsigned i = 0; i < nrows; ++i)
    matrix[i] = NULL;

  try {
    for (unsigned i = 0; i < nrows; ++i)
      matrix[i] = new Fred[ ncols[i] ];

    for (unsigned i = 0; i < nrows; ++i) {
      for (unsigned j = 0; j < ncols[i]; ++j) {
        someFunction( matrix[i][j] );
      }
    }

  }
  catch (...) {
    for (unsigned i = nrows; i > 0; --i)
      delete[] matrix[i-1];
    delete[] matrix;
    throw;    // Re-throw the current exception
  }

}

1/总是如此谨慎地初始化是牵强的还是非常合适的?

2/ 他们这样做是因为他们处理的是非内置类型吗?代码是否与 相同(具有相同的谨慎程度)double* matrix = new double[nrows];

谢谢

编辑

部分答案在常见问题解答的下一项中

4

2 回答 2

2

如此小心的原因是,如果这些分配中的任何一个失败,或者如果 Fred 构造函数抛出异常,就会发生内存泄漏。如果您要在调用堆栈的较高位置捕获异常,则您分配的内存没有句柄,这就是泄漏。

1)它是正确的,但通常如果你要费这么多麻烦来防止内存泄漏,你宁愿使用std::vectorstd::shared_ptr(等等)来为你管理内存。

2) 内置类型也是如此,但至少唯一会抛出的异常是std::bad_alloc分配失败。

于 2013-03-15T14:07:01.067 回答
0

我认为这取决于目标平台和系统要求。如果安全是一个高优先级和/或如果你可以用完内存,那么不,这并不牵强。但是,如果您不太关心安全性并且您知道您系统的用户将拥有充足的可用内存,那么我也不会这样做。

它不取决于是否使用内置类型。常见问题解答解决方案是将指向行的指针清空,以便在发生异常时,仅删除已创建的那些行(而不是某些随机内存位置)。

也就是说,我只能赞同 R. Martinho Ferndandes 的评论,即您应该为此使用 STL 容器。管理自己的记忆既乏味又危险。

于 2013-03-15T14:03:58.333 回答