在我的代码中,我在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;
}
答案 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)
{
//...
}
除非不使用new
和delete
。错误地使用它们会导致内存泄漏以及指针悬空和重复删除的错误。例如,您尝试使用main
来清理delete []z;
中的内存,但是new-expression被评估为11个delete-expression,因此错过了删除行数组{{1 }},z[0]
,... z[1]
。使用z[9]
,std::unique_ptr
,std::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