【问题标题】:Accessing double pointer causes segmentation fault访问双指针导致分段错误
【发布时间】:2011-09-16 11:06:06
【问题描述】:

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

我不想让我的main() 杂乱无章的行(其他人将不得不阅读此代码..),因此想将问题划分为子功能。我做了一个函数,它接受一个双指针并返回一个矩阵,但为什么我不能在函数外访问它?当我尝试时,我的代码 segfaults(标记如下)。如何在 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;
}

【问题讨论】:

  • 值 10^-8 不是使用 pow 计算出来的,而是可以写成常量 1e-8

标签: c++ pointers segmentation-fault


【解决方案1】:

归还:

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

主要...

double **A = makematrix(N);

【讨论】:

  • 别忘了delete [] A它。在这样一个小程序中不是什么大问题,但记住谁拥有指针是一个好习惯。
  • @DanS:如果你打算这样做,那么你也应该delete A[i] for i = 0..N-1。但坦率地说,这在一个简单的批处理式程序中是一种浪费。
【解决方案2】:
//This part segfaults
  for(i=0; i<N; i++)

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

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

【讨论】:

  • 不知何故,我怀疑double **&amp;A 会很快赢得选美比赛。可怜的雅各比。
【解决方案3】:

因为当您将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++ 中。

【讨论】:

    【解决方案4】:

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

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

    这样你的变量就会改变,所以 A 现在是一个输出参数。

    【讨论】:

      【解决方案5】:

      要快速修复代码,请使用传递引用解决方案,它比三重指针更容易阅读。

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

      【讨论】:

        猜你喜欢
        • 2018-02-20
        • 2018-03-05
        • 2021-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-02
        • 2013-07-26
        相关资源
        最近更新 更多