views:

84

answers:

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?

#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;
}
+1  A: 

That's some pretty contorted syntax. Usually when you make a 2D array:

  • The declaration is simply int *p;
  • The allocation is simply p = malloc(a*b*sizeof(int));
  • You cannot write p[i][j]. You must do one of several things - either make a secondary array int **q that contains row pointers to be able to write q[i][j] (better performance and legibility), or write p[b*i + j] (fewer steps).

Additionally, note that:

  • Your printf will spew garbage due to the missing %d parameter.
  • Since C is not typesafe, using scanf will hide any errors in indirection that you may make.

About the closest thing I could think of that remotely resembles what you were trying to do:

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

int main()
{
    int i, j;

    const int a = 3, b = 4;
    int m[4][3];
    int (*p[4])[3];

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

It compiles and functions as expected, but it's pointlessly complicated. p is an array of pointers to arrays.

Reinderien
I was writing the exact same "contorted syntax" line when you placed your answer. And indeed, n0nChun read his answer, he's not just plainly giving you code but actual way of figuring this out. And please work on your code formatting and your coding style, this would be more of a reason to get these types of errors / mistakes.
Yonathan Klijnsma
@Yon: I no the other way of doing it, i was just experimenting with this one.
n0nChun
@Rein: I actually wanted to know what is wrong with the code i have written and not on how to go around it to get the problem solved.
n0nChun
If you "no [sic] the other way of doing it", and the other way of doing it is ten times more simple and easier to understand, then...?
Reinderien
Anyway, not only is what you're trying to do a terrible idea, it's impossible. Since `a` and `b` are not constants, you can't form an array type whose length is `a` or `b`. If they were constant you could, but then that would defeat the whole purpose of using malloc.
Reinderien
infact, the size should not even be there at all, pointer types do not need a size specification. Frankly i am not convinced by the answer.
n0nChun
+1  A: 

This statement has several problems:

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

First, malloc returns a void*. You are casting that pointer using (int (*(*p)[b])[a]) which yields a value, not a data type. That isn't a valid cast, so that's one reason that the compiler is yelling at you. At this point, p hasn't been initialized so the de-referencing taking place here can crash your program if this statement was executed.

Inside your malloc call, you are using sizeof(int (*p)[a]). The statement int (*p)[a] isn't a valid C statement.

It seems that you are making this a bit more complex that it needs to be. There are two ways of building a 2D array. You can build an array using malloc(a * b * sizeof(int)) as Reinderien explains. You can also build a 1D array of pointers, each pointing to an array of type int. From your code, it seems you are trying to do the latter.

The easier way to do this would be something like this:

int **p;
... get input from user ...
// Declare an array of int pointers of length b
p = malloc(b * sizeof(int*));

// For each int* in 'p' ...
for (i = 0; i < b; ++i) {
    // ... allocate an int array of length 'a' and store a pointer in 'p[i]' ..
    p[i] = malloc(a * sizeof(int));
    // ... and fill in that array using data from the user
    printf("\t\bEnter Column %d\t\n");
    for(j = 0; j < a; j++)
        scanf("%d", &p[i][j]);
}

Using this method of building a 2D array allows you to use the syntax p[x][y]. Since p is a pointer-to-pointer, p[x] is a pointer to an array and p[x][y] is an item in the pointed-to array.

bta