如何引用 2D 指针?

How to reference a 2d pointer?

本文关键字:2D 指针 引用 何引用      更新时间:2023-10-16

在我的代码中,我在main之外创建了一个函数,该函数创建一个1D数组并初始化为0。

void create_grid(double *&y, int Npoints)
{
y = new double[Npoints];
for (int i = 0; i < Npoints; i++)
{
y[i] = 0;
}
}

如果我没有在函数中声明为double *&y的语法,我就无法访问y的值。

我尝试对 2D 数组做同样的事情,但我不知道语法。我尝试了&&**y&*&*y但没有用。有谁知道如何在 main 之外创建一个函数,该函数初始化 2d 动态数组,以便我可以在 main 中使用它?

例如:

void create_grid_2D(double **&&y, int Npoints1, int Npoints2)
{
y = new double*[Npoints1];
for (int i = 0; i < Npoints1; i++)
{
y[i] = new double[Npoints2];
}
for (int i = 0; i < Npoints1; i++)
{
for (int j = 0; j < Npoints2; j++)
{
y[i][j] = 0;
}
}
}
int main()
{
int N = 10;
double **z;//correcting this line, i wrote z** 
create_grid_2D(z, N, N);
delete[]z;
return 0;
}

C++不允许形成指向引用或引用的指针。 (字符之间没有空格,&&是一个单一的标记,意思是完全不同的东西。

而且您的声明double z**;不正确-您可能是指double **z;.

要编写一个通过引用double **z参数的函数,你只需要一个对指向指针的指针的引用:

void create_grid_2D(double **&y,int Npoints1,int Npoints2)
{
//...
}

除了不要使用newdelete。 稍微错误地使用它们会导致内存泄漏和悬空指针和双重删除的错误。 例如,您尝试使用delete []z;清理main内存,但新表达式被计算了 11 次到您的一个删除表达式,因此这错过了删除行数组z[0]z[1]、...z[9]. 使用std::unique_ptrstd::shared_ptrstd::vector或其他RAII(资源分配即初始化(工具,几乎总有更好、更简单的方法。

所以我将函数更改为:

void create_grid_2D(std::vector<std::vector<double>>& y,
unsigned int Npoints1,
unsigned int Npoints2)
{
y.assign(Npoints1, std::vector<double>(Npoints2, 0.0));
}
int main()
{
unsigned int N=10;
std::vector<std::vector<double>> z;
create_grid_2D(z, N, N);
// No manual cleanup necessary.
}

或者甚至使用返回值而不是分配参数:

std::vector<std::vector<double>> create_grid_2D(
unsigned int Npoints1,
unsigned int Npoints2)
{
return std::vector<std::vector<double>>(
Npoints1, std::vector<double>(Npoints2, 0.0));
}
int main()
{
unsigned int N=10;
std::vector<std::vector<double>> z = create_grid_2D(N, N);
}

解决/编写如此复杂的引用的一个简单技巧是(为了解决这个问题而简化版本 - 存在大括号会稍微复杂一些(:从变量名称开始,然后逐步向左移动。在您的情况下:

y

y是...

& y

y是一个参考...

*& y

y是对指针的引用...

**& y

y是对指向指针的指针的引用...

double**& y

y是对指向双精度的指针的指针的引用

因此,正确的定义是:

void create_grid_2D(double**& y,int Npoints1,int Npoints2)

但正如评论中提到的,请真正考虑避免使用原始指针,以支持std::vector和其他标准容器。

所以你想要一个指向指针的指针的引用。

2D 指针int**,引用int**&。这就是您想要使用的。

然后,您应该使用容器或至少一个智能指针。

这种方法与您目前拥有的方法略有不同,但基本上您想要一个 2D 网格,而另一个名称只是 MxN 矩阵!我们可以通过简单的模板结构非常轻松地做到这一点。此模板类将保存所有内容,而无需将数据直接放入动态内存中。然后,一旦你有了要使用的类对象,我们就可以使用智能指针将其放入动态内存中!

#include <iostream>
#include <memory>
template<class T, unsigned M, unsigned N>
class Matrix {
static const unsigned Row = M;
static const unsigned Col = N;
static const unsigned Size = Row * Col;
T data[Size] = {};
public: 
Matrix() {};
Matrix( const T* dataIn ) {
fillMatrix( dataIn );
}
void fillMatrix( const T* dataIn );
void printMatrix() const;
};
template<class T, unsigned M, unsigned N>
void Matrix<T, M, N>::fillMatrix( const T* dataIn ) {
for ( unsigned i = 0; i < Size; i++ ) {
this->data[i] = dataIn[i];
}
}
template<class T, unsigned M, unsigned N>
void Matrix<T,M,N>::printMatrix() {
for ( unsigned i = 0; i < Row; i++ ) {
for ( unsigned j = 0; j < Col; j++ ) {
std::cout << this->data[i*Col + j] << " ";
}
std::cout << 'n';
}
}
int main() {
// our 1 day array of data
double data[6] = { 1,2,3,4,5,6 };
// create and print a MxN matrix - in memory still a 1 day array but represented as 2D array
Matrix<double,2,3> A;
A.fillMatrix( data );
A.printMatrix();
std::cout << 'n';
Matrix<double, 3,2> B( data );
B.printMatrix();
std::cout << 'n';
// Want this in dynamic memory? With shared_ptr the memory is handled for you
// and is cleaned up upon it's destruction. This helps to eliminate memory leaks
// and dangling pointers.
std::shared_ptr<Matrix<float,2,3>> pMatrix( new Matrix<float,2,3>( data ) );
pMatrix->printMatrix();
return 0;
}

输出:

1 2 3
4 5 6
1 2 
3 4
5 6
1 2 3
4 5 6