0

I wanted to initialize a 2d array using pointers to pointers and I wrote the following code.
The below code is lot of hard coding but as I am a beginner to pointers I want to do it this way.
The code is not giving the output as segmentation fault.
Everything seems well to me though.

    #include<stdio.h>  
    #include<stdlib.h>  
    int readinput1(int **a,int row,int column);
    int readinput2(int **b,int row,int column);
    int sumoftables(int **a,int **b,int **c,int row,int column);
    int displayresult(int **c,int row,int column);

int main()
    {
        int **a,**b,**c,row,column;
        printf("no.of rows of desired matrix:");
        scanf("%d",&row);
        printf("no.of columns of desired matrix:");
        scanf("%d",&column);
        a=(int**)malloc(row*column*sizeof(int));>can i do the memory allocation like this
        readinput1(a,row,column);
        b=(int**)malloc(row*column*sizeof(int));
        readinput2(b,row,column);
        c=(int**)malloc(row*column*sizeof(int));
        sumoftables(a,b,c,row,column);
        printf("\n\n\n");
        displayresult(c,row,column);

    }
    int readinput1(int **a,int row,int column)
    {
        int p,q;
        for(p=0;p<row;p++)
        {
            for(q=0;q<column;q++)
            {
                scanf("\n%x",(*(a+p)+q));
            }
        }
        return 0;
    }


    int readinput2t2(int **b,int row,int column)
    {
        int p,q;
        for(p=0;p<row;p++)
        {
            for(q=0;q<column;q++)
            {
                scanf("\n%x",(*(b+p)+q));
            }
        }
        return 0;
    }
    int sumoftables(int **a,int **b,int **c,int row,int column)
    {
        int p,q;
        for(p=0;p<row;p++)
        {
            for(q=0;q<column;q++)
            {
                *(*(c+p)+q)=*(*(a+p)+q)+*(*(b+p)+q);
            }
        }
                  return 0;
    }
    int displayresult(int **c,int row,int column)
    {
        int r,s;
        for(r=0;r<row;r++)
        {
            for(s=0;s<column;s++)
            {
                printf("\t%d",*(*(c+r)+s));
            }
            printf("\n");
        }
        return 0;
    }


  [1]: https://i.stack.imgur.com/aj1AI.png
Cœur
  • 37,241
  • 25
  • 195
  • 267
  • 2
    Pointers to pointers are not 2d arrays: http://stackoverflow.com/questions/4470950/why-cant-we-use-double-pointer-to-represent-two-dimensional-arrays – Ilja Everilä Feb 08 '17 at 19:28
  • `a=(int**)malloc(row*column*sizeof(int));` is wrong, you need to reserve space for n (number of rows) _"pointers"_ to `int`, instead: `a = malloc(row * sizeof(int *));` or better yet `a = malloc(row * sizeof *a);`, same for `b` and `c`, and then you need to reserve space for each row of the table using `a[i] = malloc(column * sizeof **a);` in a loop. – David Ranieri Feb 08 '17 at 19:30
  • what you have done is just creating a single dimensional array of size row*col and not a two dimensional array. – GAURANG VYAS Feb 08 '17 at 19:31

1 Answers1

1

You can allocate memory for 2D array with this code:

void array_2d_allocate(int ***a, int row, int column)
{
    *a =(int**)malloc(row*sizeof(int*));
    for(int i=0; i < row; i++){
        (*a)[i] = (int*)malloc(column*sizeof(int));
    }
}

int main()
{
    int **a,**b,**c,row,column;
    printf("no.of rows of desired matrix:");
    scanf("%d",&row);
    printf("no.of columns of desired matrix:");
    scanf("%d",&column);
    array_2d_allocate(&a, row, column);
    readinput1(a,row,column);
    array_2d_allocate(&b, row, column);
    readinput2(b,row,column);
    array_2d_allocate(&c, row, column);
    sumoftables(a,b,c,row,column);
    printf("\n\n\n");
    displayresult(c,row,column);
}
aldarel
  • 446
  • 2
  • 7
  • +1 for casting the result of malloc(), which is a good example for double-checking the correctness of the assignment here. – Ctx Feb 08 '17 at 19:49
  • 2
    This doesn't create a true 2D array; it creates an array of pointers, each of which points to a separate array of `int`. The rows are not going to be contiguous in memory; there will be a gap between `arr[0][n-1]` and `arr[1][0]`. That's not necessarily a problem, but people need to be aware of the difference. – John Bode Feb 08 '17 at 19:51
  • 3
    @ctx: *strongly* disagree - casting the result of `malloc` is unnecessary as of C89, it increases your maintenance burden, it makes code harder to read, and under C89 it would suppress a diagnostic if you forgot to include `stdlib.h` or otherwise didn't have a declaration for `malloc` in scope. `T *a = malloc( sizeof *a * number_of_elements);` will *always* do the right thing, regardless of the type of `a`. You should only cast the result of `malloc` if you're using a pre-C89 implementation or compiling as C++ (in which case you should be using the `new` operator instead). – John Bode Feb 08 '17 at 19:56
  • @JohnBode I know the arguments, and they are all mood in my eyes. It does not increase maintenance burden at all, it makes code in many cases better readably and it enables the compiler to show up mistakes early (in this case for example if the level of dereference of `a` was wrong). The stdlib.h argument is a joke, too, since there probably will be many other warnings if forgotten. – Ctx Feb 08 '17 at 19:59
  • @ctx: Re: `stdlib.h` - not a joke. I got bit by it more than once. It's no longer a problem as of C99 (implicit typing is no longer allowed), but yes, casting the result of `malloc` *really did* supress a diagnostic if you didn't have a declaration in scope, and you'd wind up with a conversion from `void *` to `int` to some other pointer type, which occasionally caused subtle runtime errors that took way too long to debug. – John Bode Feb 08 '17 at 20:35
  • @JohnBode Sorry, just to have a warning about an implicit declaration of malloc() is not a significant reason to omit all casts of it. Especially when the left-hand side of the assignment is non-trivial (macro-expansions, dereferences, indexed arrays of multiple dimensions) it shows the reader (and the compiler, which can now warn on errors) what type exactly is expected. Of course, some (minimalist) people may find that information redundant and useless, but I do not accept that casting the result of malloc is "strongly discouraged". – Ctx Feb 08 '17 at 20:48