0

Я получаю ошибку сегментации при запуске этого кода. Кто-нибудь знает, почему? Благодарю.C - ошибка сегментации умножения матрицы

#include <stdio.h> 

int main() 
{ 
    double **m1, **m2, **mr; 
    int m1_rows, m1_cols, m2_rows, m2_cols, mr_rows, mr_cols; 
    int i, j, k; 

    printf("Enter number of rows for matrix 1: "); 
    scanf("%d", &m1_rows); 

    printf("Enter number of columns for matrix 1: "); 
    scanf("%d", &m1_cols); 

    printf("Enter number of rows for matrix 2: "); 
    scanf("%d", &m2_rows); 

    printf("Enter number of columns for matrix 2: "); 
    scanf("%d", &m2_cols); 

    //allocate memory for matrix 1 m1 
    m1 = (double **) calloc(m1_rows, sizeof(double *)); 
    for (i = 0; i < m1_rows; i++) { 
     m1[i] = (double *) calloc(m1_cols, sizeof(double)); 
    } 

    //allocate memory for matrix 2 m2 
    m2 = (double **) calloc(m2_rows, sizeof(double *)); 
    for (i = 0; i < m2_rows; i++) { 
     m2[i] = (double *) calloc(m2_cols, sizeof(double)); 
    } 

    //allocate memory for sum matrix mr 
    mr = (double **) calloc(mr_rows, sizeof(double *)); 
    for (i = 0; i < mr_rows; i++) { 
     mr[i] = (double *) calloc(mr_cols, sizeof(double)); 
    } 

    //assign mr_rows and mr_cols 
    mr_rows = m1_rows; 
    mr_cols = m2_cols; 

    //initialize product matrix 
    for (i = 0; i < m1_rows; i++) { 
     for (j = 0; j < m2_cols; j++) { 
      mr[i][j] = 0; 
     } 
    } 

    //perform matrix multiplication 
    for (i = 0; i < m1_rows; i++) { 
     for (j = 0; j < m2_cols; j++) { 
      mr[i][j] = 0; 
      for (k = 0; k < m1_cols; k++) { 
       mr[i][j] += m1[i][k] * m2[k][j]; 
      } 
     } 
    } 

    //print result 
    for (i = 0; i < mr_rows; i++) { 
     for (j = 0; j < mr_cols; j++) { 
      printf("%f\t", mr[i][j]); 
     } 
    } 

    //free memory m1 
    for (i = 0; i < m1_rows; i++); { 
     free(m1[i]); 
    } 
    free(m1); 

    //free memory m2 
    for (i = 0; i < m2_rows; i++); { 
     free(m2[i]); 
    } 
    free(m2); 

    //free memory mr 
    for (i = 0; i < mr_rows; i++); { 
     free(mr[i]); 
    } 
    free(mr); 

    return 0; 
} 

Я побежал, используя Valgrind valgrind --tool=memcheck a.out для получения дополнительной информации о сбое сегментации, но результат был более 30000 ошибок, так что не печатать их.

+3

Запустите его в GDB, чтобы идентифицировать строку. Тогда исправьте это. Затем исправьте ошибки 30000 Valgrind. Затем продолжайте развиваться. –

+1

@OliCharlesworth На самом деле я бы посоветовал сначала прочитать код, чтобы отладить это. Это всегда должно быть первой линией подхода, а не достигать инструментов. Это приводит к пониманию. –

+0

@DavidHeffernan: Возможно, на 30-строчном приложении. Я бы не стал визуально проверять 10000-строчную кодовую базу, чтобы выяснить, где произошла ошибка seg ... –

ответ

2

Вы не назначаете mr_rows и mr_cols. Они должны быть установлены таким образом:

mr_rows = m1_rows; 
mr_cols = m2_cols; 

Эта линия не хорошо:

mr[i][j] += m1[i][k] * m2[k][j]; 

Это будет доступ к элементам вне границ, не в последнюю очередь потому, что k не инициализированы. Вам нужна эта строка кода внутри трех вложенных циклов. В самом деле, вы можете также свернуть нулевой код.

for(i=0; i<m1_rows; i++){ 
    for(j=0; j<m2_cols; j++){ 
     mr[i][j] = 0; 
     for(k=0; k<m1_cols; k++){ 
      mr[i][j] += m1[i][k]*m2[k][j]; 
     } 
    } 
} 

Кроме того, все ваши блоки освобождения памяти ошибочны. Вместо

for(i=0; i<m1_rows; i++);{ 
    free(m1[i]); 
} 
free(m1); 

следует читать

for(i=0; i<m1_rows; i++){ 
    free(m1[i]); 
} 
free(m1); 

Это паразитный точка с запятой убивает вас.

Вам также необходимо выполнить проверку того, что количество столбцов в m1 равно числу строк в m2, то есть на тест m1_cols == m2_rows.

Конечная точка. Здесь вы копируете свой код ужасно. У вас нет трех одинаковых для циклов для выделения матрицы и трех одинаковых для циклов для освобождения. Извлеките эти операции в вспомогательные функции, которые можно вызвать из main.

Это все, что я могу найти!

+0

Я все еще получаю ошибку сегментации. Я еще не добавил тест для проверки m1 cols на m2 rows, но я тестировал с m1 2x2 и m2 2x2, чтобы он работал нормально. Я обновил свой код. – manalishi

+0

Вы должны назначить 'mr_rows' и' mr_cols', прежде чем использовать их! –

+0

ой конечно, прежде чем я выделил память. Благодаря! – manalishi

1

Вы не присваиваете значения mr_rows and mr_cols в любом месте. Таким образом, они будут иметь значения нежелательной почты, и вы используете их для выделения памяти по вызову calloc().