2016-05-15 1 views
3

Эта программа должна попросить пользователя ввести две матрицы и предоставить сумму из двух. Когда он скомпилирован, он работает не так, как ожидалось, я считаю, что это связано с моим использованием malloc, если кто-то может помочь в этом, будем очень благодарны.Использование Malloc для добавления двух массивов HW в C

#include <stdio.h> 
#include <stdlib.h> 
#include <malloc.h> 


/*Here we declare and define our function 'matrices', which prompts the 
user for Matrix A and Matrix B and stores their values.*/ 

int matrices(int rows, int cols){ 

    int i; 

    int** matrixA = malloc(rows * sizeof(**matrixA)); 

    int** matrixB = malloc(rows * sizeof(**matrixB)); 

    printf("Enter Matrix A\n"); 

    for (i = 0; i < rows; i++){ 
     matrixA[i] = (int *) malloc(cols * sizeof(int)); 

     scanf("%d", matrixA[i]); 

    } 

    printf("Enter Matrix B\n"); 

    for (i = 0; i < rows; i++){ 
     matrixB[i] = (int *) malloc(cols * sizeof(int)); 

     scanf("%d", matrixB[i]); 

    } 

    return 0; 
} 

/*Here we declare and define our function 'sum', which sums Matrix A and 
Matrix B and provides us with the summation of the two in the 
variable 'matrixSum'*/ 

int sum(int rows, int cols){ 

    int i; 

    int** matrixA = malloc(rows * sizeof(**matrixA)); 

    int** matrixB = malloc(rows * sizeof(**matrixB)); 

    int** matrixSum = malloc(rows * sizeof(**matrixSum)); 



    printf("A + B =\n"); 

    for (i = 0; i < rows; i++) { 

     matrixA[i] = (int *) malloc(cols * sizeof(int)); 
     matrixB[i] = (int *) malloc(cols * sizeof(int)); 
     matrixSum[i] = (int *) malloc(cols * sizeof(int)); 

      *matrixSum[i] = *matrixA[i] + *matrixB[i]; 
     printf("%d\t", *matrixSum[i]); 


      printf("\n"); 
    } 

    return 0; 
} 
/*Here we declare and define our main function which works to prompt the user for the number of rows and columns and calls the previously declared functions. */ 

int main(void){ 

    int rows, cols; 

    int** matrixA = malloc(rows * sizeof(**matrixA)); 

    int** matrixB = malloc(rows * sizeof(**matrixB)); 

    int** matrixSum = malloc(rows * sizeof(**matrixSum)); 

    printf("Please enter the number of rows: "); 
    scanf("%d", &rows); 
    printf("Please enter the number of columns: "); 
    scanf("%d", &cols); 


    matrices(rows, cols); 
    sum(rows, cols); 

    free(matrixA); 
    free(matrixB); 
    free(matrixSum); 

    return 0; 
} 
+0

Я думаю, 'int ** matrixA = malloc (rows * sizeof (** matrixA));' abd другие строки, подобные этому, должны быть похожими на 'int ** matrixA = malloc (rows * sizeof (* matrixA)); , Кроме того, явное выражение результата 'malloc()' явно считается [не хорошим] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – MikeCAT

+0

'scanf ("% d ", matrixA [i]);' ОК, но выглядит странно. Он будет считывать данные только для первого элемента массива. – MikeCAT

+0

как еще я мог бы пойти на часть scanf? –

ответ

0
matrixA[i] = (int *) malloc(cols * sizeof(int)); 

Это не должно быть sizeof(int*)? или

int** matrixA 

Это единственный указатель?

Если вы хотите динамически выделить 2d-массив из целых чисел, вы начинаете с int **, выделяете кучу int * для него, а затем для каждого из int * вы выделяете кучу ints ,

int ** array2d = malloc(rows * sizeof(int*)); 
for(int i = 0; i < rows; i++) { 
    array2d[i] = malloc(columns * sizeof(int)); 
    for (int j = 0; j < columns; j++) { 
     scanf("%d\n", &array2d[i][j]); 
    } 
} 
+0

haha ​​Я не совсем уверен, я на самом деле хотел опубликовать это как вопрос, поскольку программа не выполнялась должным образом. –

+0

Я предполагаю, что это не должно быть связано с тем, что 'matrixA [i]' является типом 'int *' и ему присваивается указатель на (первый элемент) массива 'int'. – MikeCAT

+0

проблема с моим кодом заключается в том, что при компиляции он не позволяет мне вводить достаточное количество столбцов и строк и возвращает 0 –

0

Проблема в цикле for. Malloc внутри цикла выглядит нормально, однако вам нужен еще один вложенный цикл для сканирования всех строк и столбцов матрицы.

for (i = 0; i < rows; i++){ 
    matrixA[i] = (int *) malloc(cols * sizeof(int)); 
    for (j=0; j<cols; j++) 
    { 
     scanf("%d", &matrixA[i][j]); 
    } 
} 
+0

'scanf ("% d ", matrixA [i] [j]);' -> * неопределенное поведение *: передача данных с неправильным типом и использование значения в выделенном буфере через 'malloc()' и не инициализирован. – MikeCAT

+0

, и он выделяет int, а не int *, поэтому, если int меньше, вы записываете за пределы – xaxxon

+0

@xaxxon, согласно моему пониманию, он должен выделять sizeof (int) для matrixA [i]. Пожалуйста, объясните свою точку зрения –

1
  • Размер что указываемого int** matrixA; будет sizeof(*matrixA), не sizeof(**matrixA). В средах, в которых размер указателей и int отличается, использование последнего сделает буфер слишком маленьким.
  • В функции matrices(), некоторые данные считываются и затем отбрасываются. Также происходит утечка памяти.
  • В функции sum() используются неопределенные значения в буфере, выделенные через malloc() и не инициализированные, и не определено поведение.
  • Говорят, you shouldn't cast the result of malloc() in C.

Чтобы исправить:

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

Вот фиксированный код с проверкой ошибок:

#include <stdio.h> 
#include <stdlib.h> 
#include <malloc.h> 

void matrices(int rows, int cols, int*** matrixA, int*** matrixB){ 

    int i, j; 

    *matrixA = malloc(rows * sizeof(**matrixA)); 
    if (*matrixA == NULL){ 
     perror("matrixA malloc"); 
     exit(1); 
    } 

    *matrixB = malloc(rows * sizeof(**matrixB)); 
    if (*matrixB == NULL){ 
     perror("matrixB malloc"); 
     exit(1); 
    } 

    printf("Enter Matrix A\n"); 

    for (i = 0; i < rows; i++){ 
     (*matrixA)[i] = malloc(cols * sizeof(int)); 
     if ((*matrixA)[i] == NULL){ 
      perror("matrixA[i] malloc"); 
      exit(1); 
     } 

     for (j = 0; j < cols; j++){ 
      if (scanf("%d", &(*matrixA)[i][j]) != 1){ 
       fputs("matrixA read error\n", stderr); 
       exit(1); 
      } 
     } 

    } 

    printf("Enter Matrix B\n"); 

    for (i = 0; i < rows; i++){ 
     (*matrixB)[i] = malloc(cols * sizeof(int)); 
     if ((*matrixB)[i] == NULL){ 
      perror("matrixB[i] malloc"); 
      exit(1); 
     } 

     for (j = 0; j < cols; j++){ 
      if (scanf("%d", &(*matrixB)[i][j]) != 1){ 
       fputs("matrixB read error\n", stderr); 
       exit(1); 
      } 
     } 

    } 

} 

void sum(int rows, int cols, int** matrixA, int** matrixB, int*** matrixSum){ 

    int i, j; 

    *matrixSum = malloc(rows * sizeof(**matrixSum)); 
    if (*matrixSum == NULL){ 
     perror("matrixSum malloc"); 
     exit(1); 
    } 

    printf("A + B =\n"); 

    for (i = 0; i < rows; i++) { 

     (*matrixSum)[i] = malloc(cols * sizeof(int)); 
     if ((*matrixSum)[i] == NULL){ 
      perror("matrixSum[i] malloc"); 
      exit(1); 
     } 

     for (j = 0; j < cols; j++){ 
      (*matrixSum)[i][j] = matrixA[i][j] + matrixB[i][j]; 
      printf("%d\t", (*matrixSum)[i][j]); 
     } 

     printf("\n"); 
    } 

} 
/*Here we declare and define our main function which works to prompt the user for the number of rows and columns and calls the previously declared functions. */ 

int main(void){ 

    int rows, cols; 

    int i; 

    int** matrixA; 
    int** matrixB; 
    int** matrixSum; 

    printf("Please enter the number of rows: "); 
    if (scanf("%d", &rows) != 1){ 
     fputs("rows read error\n", stderr); 
     return 1; 
    } 
    printf("Please enter the number of columns: "); 
    if (scanf("%d", &cols) != 1){ 
     fputs("cols read error\n", stderr); 
     return 1; 
    } 

    matrices(rows, cols, &matrixA, &matrixB); 
    sum(rows, cols, matrixA, matrixB, &matrixSum); 

    for (i = 0; i < rows; i++) { 
     free(matrixA[i]); 
     free(matrixB[i]); 
     free(matrixSum[i]); 
    } 

    free(matrixA); 
    free(matrixB); 
    free(matrixSum); 

    return 0; 
} 

Обратите внимание, что указывается на *matrixA является **matrixA, поэтому использование sizeof(**matrixA) теперь правильно.

+0

wow, что было потрясающе спасибо. Еще один быстрый вопрос, мне не разрешают у меня есть цикл for в main, так как я могу освободить место? Я бы создал другую функцию только для этой цели или сделал это в других функциях, которые я ранее имел? –

+0

Создание другой функции кажется хорошим. – MikeCAT

+0

Пробовал создавать функцию и не работал так что я попытался создать функцию void w аргументов строк, matrixA, matrixB и matrixSum и включил цикл for для освобождения пространства, но он не работает, как я думал .... –