使用new分配多维数组

时间:2013-03-15 13:56:21

标签: c++ exception initialization try-catch new-operator

当我使用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];相同(具有相同的谨慎程度)?

由于

编辑

部分答案在next item in FAQ

2 个答案:

答案 0 :(得分:2)

这种小心的原因是,如果任何这些分配失败,或者Fred构造函数抛出,你将会发生内存泄漏。如果你要在callstack上面捕获异常,那么你没有处理你分配的内存,这是一个泄漏。

1)这是正确的,但一般来说,如果你要防止内存泄漏这么麻烦,你宁愿使用std::vectorstd::shared_ptr(等等)来管理内存对你而言。

2)对于内置类型,它是相同的,但至少如果分配失败,则抛出的唯一异常是std::bad_alloc

答案 1 :(得分:0)

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

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

那就是说,我只能说第二个R. Martinho Ferndandes的评论,你应该使用STL容器。管理自己的记忆是乏味和危险的。