2

I want to scan a 2D array with the help of pointers and have written this code, could you tell me why the compiler gives errors? I know how to use double pointers to do the same, i was experimenting with this one.

#include<stdio.h>
#include<stdlib.h>
int main(void) {
    int i,j,n,a,b;
    int (*(*p)[])[];
    printf("\n\tEnter the size of the matrix in the form aXb\t\n");
    scanf("%dX%d",&a,&b);
    p=(int (*(*p)[b])[a])malloc(b*sizeof(int (*p)[a]));
    for(i=0;i<b;i++) {
            p[i]=(int (*p)[a])malloc(a*sizeof(int));
            printf("\t\bEnter Column %d\t\n");
            for(j=0;j<a;j++)
                    scanf("%d",&p[i][j]);
    }
    return 0;
}
3
  • It could help to list the compiler errors, you know. ;-) Commented Sep 18, 2010 at 8:55
  • What do you mean by 'this one' ? The construct (int (*(*p)[b])[a]) ?? What should that do ? My gcc seems not to like that. Commented Sep 18, 2010 at 9:04
  • determinant.c:9: error: expected ‘)’ before ‘p’ determinant.c:9: error: expected ‘)’ before ‘[’ token determinant.c:9: error: expected ‘)’ before ‘[’ token determinant.c:9: error: expected ‘;’ before ‘malloc’ determinant.c:11: error: invalid use of array with unspecified bounds determinant.c:11: error: expected ‘)’ before ‘p’ determinant.c:11: error: expected ‘)’ before ‘[’ token determinant.c:11: error: invalid use of array with unspecified bounds determinant.c:11: error: expected ‘;’ before ‘malloc’ determinant.c:14: error: invalid use of array with unspecified bounds Commented Sep 18, 2010 at 9:14

3 Answers 3

1

You are using pointers to arrays, so you shouldn't index them directly, as p[i] will give *(p+i) i.e. an array following the one pointed to by p, rather than an element of p.

In C, void* will convert to any pointer type, so you don't need to cast the result of malloc. If you do put the casts in, it can mask errors, for example if you are trying to assign to a non-pointer ( such as p[i] ).

In the malloc for p, sizeof(int (*p)[a]) should either use a type or an expression, not a declaration. p is a pointer to an array of pointers to arrays of int, so the type of the elements of *p is int (*)[].

So this compiles without error or warning on gcc:

#include<stdio.h>
#include<stdlib.h>
int main ( void )
{
    int i, j, n, a, b;

    int ( * ( * p ) [] ) [];

    printf ( "\n\tEnter the size of the matrix in the form aXb\t\n" );

    scanf ( "%dX%d", &a, &b );

    p = malloc ( b * sizeof ( int ( * ) [] ) );

    for ( i = 0;i < b;i++ ) {
        ( *p ) [i] = malloc ( a * sizeof ( int ) );
        printf ( "\t\bEnter Column %d\t\n", i );
        for ( j = 0;j < a;j++ )
            scanf ( "%d", & ( * ( *p ) [i] ) [j] );
    }


    return 0;
}

However, since there is no advantage in using a pointer to an array against using a pointer to its first element but it does mean you have to dereference before taking the element, it is much easier to use the pointer to a pointer form.

Sign up to request clarification or add additional context in comments.

1 Comment

This is a brilliant answer. Thank you! :)
1

Do you know what int (*(*p)[])[] is?
Try cdecl.org ... http://cdecl.ridiculousfish.com/?q=int+%28%2A%28%2Ap%29%5B%5D%29%5B%5D

To use a 1-dimensional array and pretend it's a 2-dimensional one

  1. declare a 1-dimensional object (pointer, array, whatever)
  2. malloc a rectangular size
  3. compute linear addressing value based on row, column, and column size
  4. use it
  5. free the array

That's it

/* Oh ... and use spaces in your code */
/* They are extremely cheap now a days */
#include <assert.h>
/* instead of asserting malloc and scanf, use proper error checking */
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int i, j, n, rows, cols;
    int *p;                                            /* 1. */

    printf("Enter the size of the matrix in the form aXb\n");
    n = scanf("%dX%d", &rows, &cols);
    assert((n == 2) && ("scanf failed"));
    p = malloc(rows * cols * sizeof *p);               /* 2. */
    assert((p != NULL) && "malloc failed");
    for (i = 0; i < rows; i++) {
            int rowindex = i * cols;                   /* 3. */
            for (j = 0; j < cols; j++) {
                    n = scanf("%d", &p[rowindex + j]); /* 3. and 4. */
                    assert((n == 1) && "scanf failed");
            }
    }
    free(p);                                           /* 5. */
    return 0;
}

Comments

0

You are unnecessarily complicating the problem of accessing array elements using pointers. Try to use a simple pointer-to-pointer p.

int **p;
...
p=malloc(a*sizeof(int *));   //create one pointer for each row of matrix
...
for(i=0;i<a;i++)
{
...
p[i]=malloc(b*sizeof(int));  //create b integers in each row of matrix
...
}

1 Comment

You might want to "use" the object (rather than the type) as argument to the sizeof operator. If you change p to double **p in the future, you won't need to change the lines with mallocs p = malloc(a * sizeof *p); and p[i] = malloc(b * sizeof *p[i]);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.