通过函数

时间:2015-07-05 13:02:12

标签: c++ arrays valgrind

我正在开发一个需要许多动态大小的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并发现它符合

的条件
  • 绝对丢失,有时
  • 可能丢失

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

3 个答案:

答案 0 :(得分:2)

按以下方式编写函数

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>>而不是自己动态分配数组。

答案 1 :(得分:2)

假设有必要将指针传递给函数以初始化它......

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
 }

这样做的好处是标准的矢量类将很乐意为您管理所有内存分配和释放。

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

答案 2 :(得分:0)

一种更好的方法来编码上面的内容:

echo $result['class_name'];
echo $result['class_section'];
echo $result['class_description'];
echo $result['class_limit'];

然后你可以

#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没有问题,就像它是一个数组一样。