(C программирование) Segfault при объединении 2 одномерных массивов в 1 многомерный массив - PullRequest
0 голосов
/ 13 октября 2018

Я пишу программу, в которой я беру 2 одномерных массива и генерирую матрицу в ее наиболее упрощенной форме Ax = b.Эта часть функции принимает массивы A и b.A является A [n * n] и b является b [n].В этом разделе я попытался объединить два массива, чтобы он выглядел как фактическая матрица.Этот код работает, однако, если n будет больше 1023, это вызовет ошибку сегментации при вызове основной функции.Мне было интересно, есть ли лучший способ сделать это.Когда я попытался использовать отладчик 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 
    }

Ответы [ 2 ]

0 голосов
/ 13 октября 2018

Я предполагаю, что вы используете систему типов Unix / Linux.Сначала узнайте размер стека, набрав

ulimit -s

Это размер стека в килобайтах.В моей системе это 8 МБ.Если у вас матрица 1200x1200, для этого потребуется

1200x1201x8 appx 10Mb

Именно поэтому программа segvs.Вы создаете массив 10 МБ в стеке 8 МБ.Вопрос в том, живут ли 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;
}
0 голосов
/ 13 октября 2018
// 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
}
...