C++数组通过函数引用初始化
C++ array initialization by reference through function
我正在从事一个项目,该项目需要许多动态大小的二维数组,这些数组需要跨函数访问。
我正在处理的代码为此使用了像 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>>
而不是自己动态分配数组。
对上述内容进行编码的一个更好的方法是:
#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]
没有问题,就好像它是一个数组一样。
假设有必要将指针传递给函数以对其进行初始化...
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
}
这样做的好处是标准向量 class 会愉快地为您管理所有内存分配和释放。
通过引用传递此类向量非常容易。
我正在从事一个项目,该项目需要许多动态大小的二维数组,这些数组需要跨函数访问。
我正在处理的代码为此使用了像 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>>
而不是自己动态分配数组。
对上述内容进行编码的一个更好的方法是:
#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]
没有问题,就好像它是一个数组一样。
假设有必要将指针传递给函数以对其进行初始化...
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
}
这样做的好处是标准向量 class 会愉快地为您管理所有内存分配和释放。
通过引用传递此类向量非常容易。