繁体   English   中英

通过函数引用进行C ++数组初始化

[英]C++ array initialization by reference through function

我正在一个项目中,该项目需要许多动态大小的2D数组,并且需要跨函数进行访问。 我正在处理的代码为此使用了像double** dynArray这样的指针。

R = ...; // ROWS of the matrix, unknown prior to runtime 
C = ...; // COLUMNS of the matrix, unknown prior to runtime

double** dynArray;

检查现有代码后,我发现数组当前总是像这样初始化:

double** dynArray = new double*[R];
for(int r=0; r<R; r++){dynArray[r] = new double[C];}

为了提高可读性,我想编写一种方法来完成上述操作。 这是我想分配的

void initialize2D(double*** data, int R, int C){

    (*dynArray) = new double*[R];

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

        (*dynArray)[r] = new double[C];

        for(int c=0; c<C; c++){
            (*dynArray)[r][c] = 0;
        }
    }
}

和可用内存分别为:

void free2D(double*** data, int R, int C){

    for(int r=0; r<R; r++){
        delete[] (*data)[r];
    }
    delete *data;
}

我打算这样使用这些方法:

R = ...; // ROWS of the matrix, unknown prior to runtime 
C = ...; // COLUMNS of the matrix, unknown prior to runtime

double** dynArray;
initialize2D(&dynArray, R, C);
/* do stuff*/
free2D(&dynArray,R,C);

执行完这些功能后,我运行了Valgrind,发现这符合

  • 肯定会迷路 ,有时
  • 可能迷路了

有什么问题,通过引用进行函数初始化的正确方法是什么?

通过以下方式编写函数

double ** initialize2D( int R, int C )
{
    double **dynArray = new double *[R];

    for ( int r = 0; r < R; r++ )
    {
        dynArray[r] = new double[C]();
    }

    return dynArray;
}

void free2D( double **data, int R )
{
    for ( int r = 0; r < R; r++ ) delete [] data[r];
    delete [] data;
}

并通过以下方式调用函数

double** dynArray = initialize2D( R, C );
/* do stuff*/
free2D( dynArray, R );
dynArray = nullptr;

考虑到您可以使用标准容器std::vector<std::vector<double>>而不是自己动态分配数组。

假设有必要将指针传递给函数以对其进行初始化...

void initialize2D(double*** data, int R, int C)
{
   *data = new double*[R];

   for(int r=0; r<R; r++)
   {
      (*data)[r] = new double[C];
      for(int c=0; c<C; c++)
      {
          (*data)[r][c] = 0;
      }
   }
}

void free2D( double ***data, int R )
{
     for ( int r = 0; r < R; r++ ) delete [] (*data)[r];
     delete [] (*data);
     *data = nullptr;
}

但是,就我个人而言,我根本不会直接使用动态内存分配。 相反,我会做;

#include <vector>

//   and in your code

void some_function()
{
     std::vector<std::vector<double> > dynArray(R, std::vector<double>(C));

     //   use dynArray as if it is a 2D array.  All elements dynArray[i][j]
     //    will be initialised to zero, for i = 0 to R-1 and j = 0 to C-1

    dynArray[3][4] = 42;    // assuming R > 3 and C > 4

    // ALL memory allocated for dynArray will be released here automatically as it passes out of scope
 }

这样做的好处是标准向量类将为您愉快地管理所有内存分配和释放。

通过引用传递这样的向量很容易。

一种更好的方式来编写上面的代码:

#include <vector>

std::vector<std::vector<double>> initialise2D(int r, int c)
{
  std::vector<std::vector<double>> result(r);
  for(int i=0; i<r; ++i) result[i].reserve(c);
  return result;
}

void free2D(std::vector<std::vector<double>> &v)
{
  v.clear();
}

你可以

auto dynArray = initialise3D(20, 30);

您还应该注意,您实际上不再需要free2D 我将其保存在这里只是为了让您看到事情变得多么容易。

您还将注意到,可以使用向量,就像使用数组一样。 这就是为什么我使用方括号将result[i]像数组一样写没有问题的原因。

暂无
暂无

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

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