-1

I am trying to take integer data and store it into a dimensional array but i am unable to do it. Somebody help me please..

I tried using *(*(arr+i) + j) where arr is a pointer to the 2-D array , i and j are the loop variables, I get an error

error: invalid type argument of unary '*' (have 'int') scanf("%d", ((arr+i) + j));

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

int main(){
        int n,*arr,i,j,k;
        scanf("%d",&n);
        arr = malloc(n*n*sizeof(int));
        memset(arr,0,n*n*sizeof(int));
        for(i=0;i<n;i++){
                for(j=0;j<n;j++){
                        scanf("%d", *(*(arr+i) + j));
                }
        }
        for(i=0;i<n;i++){
                for(j=0;j<n;j++){
                        printf("%d ", *(*(arr+i) + j);
                }
                printf("\n");
        }

}

My input was:

3
11 2 4
4 5 6
10 8 -12
AKSHAY KADAM
  • 129
  • 8
  • 3
    *Why* are you using pointer arithmetic syntax rather than easy to understand array index syntax? `*(*(arr + i) + j)` is exactly equal to `arr[i][j]` (which is not only easier to understand, but also less to write). – Some programmer dude Aug 05 '19 at 12:20
  • 2
    As for your problem, `arr` ***isn't*** a "2-D array", it's a pointer to a single "array" and then you can't treat it as an array of pointers (or array of arrays), which you're doing. – Some programmer dude Aug 05 '19 at 12:21
  • @AKSHAY KADAM I never see a two-dimensional array in the presented code.:) – Vlad from Moscow Aug 05 '19 at 12:21
  • If you use a vector of values (monodimensional array), as in your code, you may point the element of the array using `arr[ x + y * maxXsize]=value`; where maxXsize is the max value for x (in other words the number of columns). – Sir Jo Black Aug 05 '19 at 12:28
  • 1
    That's a horrible duplicate which does _not_ allocate 2D arrays. Re-opening. – Lundin Aug 05 '19 at 12:37
  • A better dupe link might be [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays), but the OP isn't actually asking how to allocate the array but rather how to access it properly. – Lundin Aug 05 '19 at 12:39

2 Answers2

3

int* arr ... arr = malloc(n*n*sizeof(int)); gives you a "mangled" 2D array - it's actually a 1D array. Meaning you'll have to access it as arr[i*n + j].

Mangled arrays are mostly a thing of the past though. With modern standard C, you can replace the whole code with this:

int (*arr)[n] = malloc( sizeof(int[n][n]) );
...
for(size_t i=0; i<n; i++)
  for(size_t j=0; j<n; j++)
    scanf("%d", &arr[i][j]);
...
free(arr);

Also note, if you need to zero-initialize the whole array to zero, you are better off using calloc since it does just that.

Lundin
  • 195,001
  • 40
  • 254
  • 396
0

The type of the variable arr is int *.

int n,*arr,i,j,k;
      ^^^^

So there is no a two-dimensional array in your program.

So for example this expression

*(arr+i) + j

has type int. And this expression

*(*(arr+i) + j)

tries to dereference an object of the type int that is an object that is not a pointer.

If your compiler supports variable length arrays then the program can look like

#include <stdio.h>

int main(void) 
{
    size_t n;

    scanf( "%zu", &n );

    int a[n][n];

    for ( size_t i = 0; i < n; i++ )
    {
        for ( size_t j = 0; j < n; j++ )
        {
            scanf( "%d", *( a + i ) + j );
        }
    }

    for ( size_t i = 0; i < n; i++ )
    {
        for ( size_t j = 0; j < n; j++ )
        {
            printf( "%3d ", *( *( a + i ) + j ) );
        }
        putchar( '\n' );
    }

    return 0;
}

Its output is

 11   2   4 
  4   5   6 
 10   8 -12 

Otherwise another approach is dynamically to allocate a one-dimensional array of pointers and then correspondingly one-dimensional arrays of integers.

For example

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

int main(void) 
{
    size_t n;

    scanf( "%zu", &n );

    int **a = malloc( n * sizeof( int * ) );

    for ( size_t i = 0; i < n; i++ )
    {
        *( a + i ) = malloc( n * sizeof( int ) );
    }

    for ( size_t i = 0; i < n; i++ )
    {
        for ( size_t j = 0; j < n; j++ )
        {
            scanf( "%d", *( a + i ) + j );
        }
    }

    for ( size_t i = 0; i < n; i++ )
    {
        for ( size_t j = 0; j < n; j++ )
        {
            printf( "%3d ", *( *( a + i ) + j ) );
        }
        putchar( '\n' );
    }

    for ( size_t i = 0; i < n; i++ )
    {
        free( *( a + i ) );
    }

    free( a );

    return 0;
}

The program output will be the same as shown above.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Neither of these are good IMO. The VLA has local scope and can't be passed around. The `int **a` leads to a segmented look-up table which is not a 2D array, but just a needlessly slow construct that blocks caching and needlessly segments the heap. – Lundin Aug 05 '19 at 12:43
  • No, I'm (potentially) using a pointer to a VLA, which is a big difference. The pointed-at data will not have local scope. Also if `n` is an integer constant (through `#define`), it is just an array pointer to an array of fixed size. – Lundin Aug 05 '19 at 12:46
  • @Lundin This construction sizeof(int[n][n]) is allowed only when the compiler supports variable length arrays. If the compiler does not support VLAs then the only approach is the approach shown in my answer.:) – Vlad from Moscow Aug 05 '19 at 12:47
  • Nope it is perfectly fine to use for example `sizeof(int[4][4])` even in C90. And it doesn't really matter since no object is allocated during the sizeof call. – Lundin Aug 05 '19 at 12:50
  • @Lundin You are using constants. So it is not a specification of the variable length arrays and has nothing common with sizeof( int[n][n] ). – Vlad from Moscow Aug 05 '19 at 12:51
  • @Lundin: a VLA can be passed to functions called from where it is allocated; it can't be passed back to a calling function if it is not dynamically allocated (any more than an automatic FLA (fixed-length array) can be passed back. (You can't have static VLAs, of course, but you can have static FLAs.) It requires care to return a VLA if it is dynamically allocated. Calling other functions from where it is allocated doesn't present problems. Returning such an array does present difficulties. But "can't be passed around" is sweeping and not completely accurate. – Jonathan Leffler Aug 05 '19 at 16:56
  • @JonathanLeffler I was mostly thinking of situations such as passing it along to a thread, which would definitely be a latent bug. – Lundin Aug 05 '19 at 17:29
  • Your observation is in a comment, so 'answer-ready' clarity isn't quite mandatory. I can see a few ways to pass a VLA to a thread function; I can see lots of ways of getting it wrong when passing a VLA to a thread function, and it isn't something I'd normally try. Context is crucial… – Jonathan Leffler Aug 05 '19 at 18:04
  • I can't but a downvote an answer to a beginner that uses `*( a + i ) + j` – Antti Haapala -- Слава Україні Aug 06 '19 at 05:19