访问双指针会导致分段错误

Accessing double pointer causes segmentation fault

本文关键字:分段 错误 指针 访问      更新时间:2023-10-16

我正在QM中为特征值问题编程Jacobis方法,我刚刚开始使用c++,我想使用双指针来构造矩阵,但所涉及的物理问题需要大量代码。

我不想让我的main()中有不可读的行(其他人必须阅读这段代码(,所以我想把问题分为几个子函数。我做了一个函数,它使用双指针并返回一个矩阵,但为什么我不能在函数之外访问它?当我尝试时,我的代码segfoots(标记如下(。如何在main((之外构造矩阵,同时仍能在main()中访问它?

enter code her    enter code here
int i, j, k;  

//== BEGIN MAIN ==//
int main ()
{
  //Constants and variables          
  double **A;
  double epsilon = pow((double)10, double(-8)); //The convergence limit for jacobis   method
  int N          = 10;                          //Dimension of matrix
  char test[] =  "test";
  cout <<"The inner matrix function:"<<endl;
  makematrix(N, A);
  cout<<endl<<"The outer matrix function:"<<endl;
  //This part segfaults
  for(i=0; i<N; i++)
  {
  cout<<endl;
  for(j=0; j<N; j++)
{
  cout<<A[i][j]<<" ";
}
 }
return 0;
 }
 //== END MAIN ==//

//==Begin function definitions==//
void makematrix(int N, double **A)
{
   //Function for initializing our tridiagonal matrices for jacobis method
    A = new double*[N];
for(i=0; i<N; i++)
{
  A[i] = new double[N];
}
 for(i=0; i<N; i++)
{
  for(j=0; j<N; j++)
{
  A[i][j] = 0;
   }
     }
    //Prints the matrix declared here
    for(i=0; i<N; i++)
     {
       cout<<endl;
       for(j=0; j<N; j++)
    {
      cout<<A[i][j]<<" ";
    }
    }
 cout <<endl;
 return;
}

返回:

double** makematrix(int N) {
    double **A = new double*[N];
    ...
    return A;
}

总的来说。。。

double **A = makematrix(N);
//This part segfaults
  for(i=0; i<N; i++)

因为,传递double **A的是值(在makematrix内部进行修改(,而不是引用。将您的函数签名更改为以下内容,它应该可以工作:

void makematrix(int N, double **&A)
...                            ^^^ pass by reference

因为当您将A传递到函数中时,函数会对A副本进行操作。它将副本设置为指向new数组,但这不会影响原始A

一种解决方案是:

double **A;
makematrix(N, &A);  // Pass address of A
...
void makematrix(int N, double ***A)
{
    (*A) = new double*[N];
    // etc.
}

即传递A的地址,使函数可以修改原来的地址。

注意:任何时候你最终需要三分球,你都可能有设计问题。尤其是在C++中。

我认为应该通过引用将指针作为参数传递。所以函数应该是这样的(我添加了一个&(:

void makematrix(int N, double **&A)

通过这种方式,您的变量将被更改,因此A现在是一个输出参数。

要快速修复代码,请使用pass-by-reference解决方案,它比三指针更容易读取。

然而,如果你想用真实的C++而不是伪装的C进行编码,那么在矩阵后面隐藏双数组复杂性的解决方案就是创建一个类。C++FAQ-Lite对您的问题进行了广泛的描述,并提供了不同的解决方法。请参阅http://www.parashift.com/c++-faq-lite/operator重载.html#faq-13.10和http://www.parashift.com/c++-faq-lite/operator重载.html#faq-13.11