Двумерный динамический массив на C

В чем может быть ошибка создания массива? Требуется вычислить сумму элементов в каждой строке и в каждом столбце.

    #include <stdio.h>
#include <malloc.h>
 
int main (void)
{
  int n, s, m;
  scanf ("%i%i", &n, &m);
  int (*arr)[m];
  arr = malloc(sizeof(*arr) * n);   // COLS is in the `sizeof`
  arr = malloc(sizeof(int[n][m]));
  for (int i = 0; i < n; i++)
    {
      for (int j = 0; j < m; j++)
    {
        scanf ("%i", &arr[i][j]);
    }
    }
 
  for (int i = 0; i < n; i++)
    {
      int sum = 0;
      for (int j = 0; j < m; j++)
    {
      sum += arr[i][j];
    }
    printf ("%i ", sum);
    }
    printf ("\n");
  for (int j = 0; j < m; j++)
    {
    int sum = 0;
    for (int i = 0; i < n; i++)
        {
         sum += arr[i][j];
        }
        printf ("%i ", sum);
    }
    printf ("\n\n");
  for (int i = 0; i < n; i++)
    {
      for (int j = 0; j < m; j++)
    {
        printf ("%i ", arr[i][j]);
    }
        printf ("\n");
    }
     
  for (int i = 0; i < n; i++)
    {
      free (arr);
    }
}

Ответы (2 шт):

Автор решения: Zhihar
arr = malloc(sizeof(*arr) * n);   // COLS is in the `sizeof`
arr = malloc(sizeof(int[n][m]));

выделили память 2 раза и оба раза одной и той же переменной присвоили? хитро :)

в общем если вы создаёте динамически двухмерный массив - т.е. массив массивов, то

  1. выделите память под n строк
  2. пройдитесь по всему массиву и выделите память для каждой строки под m столбцов

ну или выделите память под одномерный массив размером m x n но тогда и индексацию полностью берите на себя и работайте как с одномерным массивом

примерный код:

int** arr = 0;

const int cols = 10;
const int rows = 20;

arr = malloc(cols * sizeof(int*));

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

arr[8][19] = 123;

на счет голого C не уверен - вроде в цикле нельзя было задавать переменную и надо было снаружи указать int i;

→ Ссылка
Автор решения: AlexGlebe

Если делать массив в стеке то как всегда :

int arr[n][m] ;
arr[i][j] = 7;

А если стек будет выделен в куче то так :

int ( * arrp ) [n][m] = malloc(sizeof(int[n][m]));
(*arrp)[i][j] = 7;
free(arrp);

Но если вы захотите передать адрес этого массива другой функции, то придётся возится с преобразованиями типов. Некоторые программисты делают как вектор векторов. Тогда возится с типами не надо.

int * * arrpp = malloc (sizeof(int*)*n);
for (int i=0;i<n;++i)
  arrpp[i] = malloc(sizeof(int)*m);
arrpp[i][j] = 7;
for (int i=0;i<n;++i)
  free(arrpp[i]);
free(arrpp);

Всё на любителя.

→ Ссылка