如何引用2D指针?

时间:2018-10-21 18:11:37

标签: c++

在我的代码中,我在main之外创建了一个函数,该函数创建了一维数组并初始化为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;
}

4 个答案:

答案 0 :(得分:1)

解决/编写这样的复杂引用的一个简单技巧是(为解决此问题,使用了简化的版本-带有大括号的情况更加复杂):从变量名开始,并逐步移至左侧。就您而言:

  

... y

y是...

  

... & y

y是参考文献...

  

... *& y

y是对指针的引用...

  

... **& y

y是对指针的引用...

  

double**& y

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

因此,正确的定义是:

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

但是正如评论中所述,请确实考虑避免使用原始指针,而推荐使用std::vector和其他标准容器。

答案 1 :(得分:1)

C ++不允许形成指向引用的引用或指向引用的引用。 (而且字符之间没有空格,&&是单个标记,表示完全不同的东西。)

您的声明double z**;不正确-您的意思可能是double **z;

要编写一个通过引用接受参数double **z的函数,您只需要引用指向指针的指针即可:

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

除非不使用newdelete。错误地使用它们会导致内存泄漏以及指针悬空和重复删除的错误。例如,您尝试使用main来清理delete []z;中的内存,但是new-expression被评估为11个delete-expression,因此错过了删除行数组{{1 }},z[0],... z[1]。使用z[9]std::unique_ptrstd::shared_ptr或其他RAII(资源分配是初始化)工具总是有更好,更简单的方法。

所以我将功能更改为:

std::vector

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

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.
}

答案 2 :(得分:0)

因此,您希望在指向指针的指针上进行引用。

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

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

答案 3 :(得分:0)

这种方法与您目前使用的方法略有不同,但是基本上您想要一个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