0

I'm new to c language and I have an assignment to allocate a dymanic matrix inside a function, put values in it and return to main and then call to another function that prints the matrix. I know that if I want to change the matrix values inside a function I need to use '&'. But when I return to main in order to print the matrix I get "Segmentation fault (core dumped)". Can somone tell me what's wrong with my code:

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


int checkSize(int); //checking matrix size
void printMatrix(int **, int);  //print matrix
int createMatrix(int ***, int); //allocate matrix and puts values from user.

int main()
{
  int c; int **p=NULL;
  printf("enter size of a matrix\n");
  c=getchar();
  if (checkSize(c))
  {
    if((createMatrix(&p, c-'0'))!=0)
      printMatrix(p, c-'0');
  }
  return 0;
}

int checkSize(int c)
{
  if (c>'9'||c<'0')
    return 0;
  return 1;
}

int createMatrix(int ***p, int n)
{
  int m=n;
  int k;
  p=(int***)malloc(m*sizeof(int**));
  for (k=0; k<m; k++)
    p[k]=(int**)malloc(m*sizeof(int*));
  printf("enter numbers\n");
  int *l;
  int i;
  int c;
  for (i=0; i<m; i++)
  {
    k=n;
    for (l=(int*)(p)+i;k>0;l++)
    {
      c=getchar();
      if (c==EOF)
      {
        printf("error EOF");
        return 0;  
      }
      if (c>'9'||c<'0')
      {
        printf("error");
        return 0;
      }
      *l=c-'0';
      k--;
    }
  }
  return 1;
}

void printMatrix(int **p, int n)
{
  int k=n;
  int* l;
  int i;
  int m=n;
  for (i=0; i<k; i++)
  {
    m=n;
    printf("\n");
    for (l=(int*)(p)+i;m>0;l++)
    {
      printf("%d ", *l);
      m--;
    }
  }
}
Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
joe
  • 33
  • 2
  • 2
    The three stars. That's what's wrong. Don't be a three star programmer. If you want to return a matrix from a function, **put it the `return` statement**`. Not in the argument list. – n. m. could be an AI Dec 07 '17 at 10:09
  • 3
    [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays). – Lundin Dec 07 '17 at 10:18
  • 1
    Also consider putting the burden of indexing on the user, heh. Sure `matrix[i][j]` is nice, but it's quite costly to have that ragged allocation going on. Compare to an actual 2D compact array, with `matrix[i * width + j]`:one `malloc()`, one level of indirection less. – unwind Dec 07 '17 at 10:19
  • @unwind There is no need to use such "mangled" arrays since C99. See the link posted above for how to allocate an actual 2D array while still indexing with `[i][j]`. – Lundin Dec 07 '17 at 10:31

1 Answers1

1

One issue is your memory allocation. You allocate space for the wrong types and save the result incorrectly. That is

p=(int***)malloc(m*sizeof(int**));

should be

*p = malloc(m * sizeof(int*));

and

p[k]=(int**)malloc(m*sizeof(int*));

should be

(*p)[k] = malloc(m * sizeof(int));

Here is an alternative approach that doesn't operate directly on the input argument:

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

int create(int ***m, int n)
{
    int i, j;

    // Create the matrix
    int** p = malloc(n * sizeof *p);   // ToDo: Check return value
    for (i=0; i < n; ++i)
    {
        p[i] = malloc(n * sizeof **p);   // ToDo: Check return value
    }

    for (i=0; i < n; ++i)
    {
        for (j=0; j < n; ++j)
        {
            *(p[i] + j) = 10 * i + j;
        }
    }

    // Assign the matrix to the passed pointer
    *m = p;

    return 0;
}

void pm(int **m, int n)
{
    int i, j;
    for (i=0; i < n; ++i)
    {
        for (j=0; j < n; ++j)
        {
            printf("%d ", *(m[i] + j));
        }
        printf("\n");
    }
}
int main(void) {
    int** m;
    create(&m, 5);
    pm(m, 5);

    // ToDo: Add code to free memory

    return 0;
}

Output:

0 1 2 3 4 
10 11 12 13 14 
20 21 22 23 24 
30 31 32 33 34 
40 41 42 43 44 

note For clarity check of malloc return value is omitted.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63