【问题标题】:(C programming) Segfault when combining 2 one-dimensional array into 1 multi-dimensional array(C编程)将2个一维数组合并为1个多维数组时的Segfault
【发布时间】:2018-10-13 06:17:07
【问题描述】:

我正在编写一个程序,其中我采用 2 个一维数组并以最简化的形式 Ax=b 生成一个矩阵。 这部分函数接受数组 A 和 b。 A 是 A[n*n],b 是 b[n]。在本节中,我尝试组合这两个数组,使其看起来像一个实际的矩阵。 但是,如果 n 大于 1023,则此代码有效,则在调用 main 函数时会导致分段错误。我想知道是否有更好的方法来做到这一点。当我尝试使用 GDB 调试器时,它停在Y[i][j] = A[k]; 行,所以我认为这是需要修复的问题

int linsolve ( int n, double A[], double b[], double x []) {

    double Y[n][n+1];        //Creating multidimensional matrix 
    int k = 0;
    // Turns the two one dimensional array into one multidimensional 
    for (int i=0; i < n; i++){        //iterating row
        for (int j=0; j < n; j++){    // per column 

            Y[i][j] = A[k];                // adding from array A to Y 
            k++;
        }
        Y[i][n] = b[i];                 // adding from Array b to Y 
    }

【问题讨论】:

  • A 是矩阵对吧?

标签: c arrays matrix segmentation-fault


【解决方案1】:

我假设您使用的是 Unix/Linux 类型系统。首先通过键入找出堆栈大小

ulimit -s

这是堆栈大小,以千字节为单位。在我的系统上它是 8Mb。如果您有 1200x1200 矩阵,则需要

1200x1201x8 appx 10Mb

这就是程序 segvs 的原因。您正在 8Mb 堆栈上创建 10Mb 数组。问题是,A 或 b 是否也存在于堆栈中?您可能会得到一个 segv,因为您正在传递的项目是在堆栈上创建的并且大于分配的堆栈。

要解决它,请按照@shirish 的建议在堆上创建数组。 @shirish 技术的替代方法是

int linsolve ( int n, double A[], double b[], double x []) {
    double **Y = new double *[n];
    double *Ybody = new double[n * (n + 1)];
    for (int i = 0; i < n; i++) {
        Y[i] = &Ybody[i * (n + 1)];
    }

    // Turns the two one dimensional array into one multidimensional 
    int k = 0
    for (int i=0; i < n; i++){
        for (int j=0; j < n; j++){
            Y[i][j] = A[k++]; 
        }
        Y[i][n] = b[i];
    }

    // Do something

    // Free up Y before returning
    delete [] Y;
    delete [] Ybody;
}

【讨论】:

    【解决方案2】:
    // Assuming A has n * n elements
    int linsolve ( int n, double A[], double b[], double x []) {
        double **Y = new double *[n];
        for (int i = 0; i < n; i++) {
            Y[i] = new double[n + 1];
        }
        int k = 0;
        // Turns the two one dimensional array into one multidimensional 
        for (int i=0; i < n; i++){        //iterating row
    
            for (int j=0; j < n; j++){    // per column 
                Y[i][j] = A[k++];                // adding from array A to Y 
            }
            Y[i][n] = b[i];                 // adding from Array b to Y 
        }
        // Do something
        // Free up Y before returning
        for(int i = 0; i < n; i++) {
            delete [] Y[i];
        }
        delete [] Y;
        //Return int here
    }
    

    【讨论】:

    • 嗨!感谢您的回答,但不幸的是,这仍然遇到 Segfault 错误,难道只是矩阵无法处理 1200x1200 吗?
    • 您好,再次感谢您的回复。我已经找出问题所在了!基本上,如果我要在函数外部而不是内部将数组 Y 贴花。
    • 建议不要在不需要全局变量时使用它们,因为调试(在大型项目中)变得非常困难。编写好的代码很重要,但通常正确运行的解决方案足以满足需求(在小型项目中)。
    • k 应该在循环之外,否则所有行都将与矩阵的第一行具有相同的值
    猜你喜欢
    • 1970-01-01
    • 2021-04-20
    • 1970-01-01
    • 1970-01-01
    • 2021-04-26
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 2021-05-13
    相关资源
    最近更新 更多