3

I was wondering how to properly use scanf to fill out a multidimensional array.

Here's my code:

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

int main(int argc, const char * argv[]) {

int n; //number of rounds
int* sArray; //multidimensional array that holds the scores of both players
int i;

scanf("%d", &n);

sArray = (int*) calloc (n * 2, sizeof(int));


for(i=0; i<n; i++) {
    scanf("%d %d", &sArray[i][1], &sArray[i][2]); 

}

return 0;
}

It gives me an error, "Subscripted value is not an array, pointer, or vector." Any help would be much appreciated!

8
  • 1
    To dereference a two dimensional array you need a double pointer: int** sArray; Commented Jan 17, 2016 at 23:14
  • Just FYI, your #include statements should be before your main method. Commented Jan 17, 2016 at 23:23
  • 1
    Always check the function return value from scanf (the number of items successfully scanned). Commented Jan 17, 2016 at 23:26
  • To fill a two dimensional array you need two nested for loops Commented Jan 17, 2016 at 23:29
  • 1
    Should be int (*sArray)[2] = calloc (n , sizeof **sArray * 2); Commented Jan 17, 2016 at 23:36

4 Answers 4

2

A two dimentional array is defined as follows: int sArray[N][M], but since you wanted to work with the dynamic memory I offer you to take a look at a pointer to pointer at int:

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

int main()
{
    int n;
    scanf("%d", &n);
    int **sArray;
    sArray = (int **)malloc(n * sizeof(int *));

    int i;
    for(i = 0; i < n; i++)
    {
        sArray[i] = (int *)malloc(2 * sizeof(int));
        scanf("%d %d", &sArray[i][1], &sArray[i][2]);
    } 
    return 0;
}

Don't forget to clean-up after you are done with the array.

As mentioned in the commentaries, You don't need to cast the result of malloc if you work with pure c. I did this because my c++ compiler refused to compile it without this cast.

You might need to check errors during a dynamic allocation of the array. Read more here

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

9 Comments

That's fine, but please don't cast the result of malloc.
That's not really a two-dimensional array, that is 1-dimensional array of pointers to 1-dimensional arrays (with massive memory overhead in this case). It is also possible to have actual 2-dimensional array of values.
@hyde Not if the C implementation you're using doesn't have VLAs, which is possible in C11.
@szczurcio You don't need VLA if other dimension is fixed at compile time, and here it is 2. So C89 is enough. Also, C99 already has VLA.
A two dimentional array is defined as follows: int **sArray... A two dimensional array in C looks like: int array[x][y]; What you have is a pointer to pointer to int: int **array; that will be used to emulate a 2D array.
|
2

There are already a lot of good answers here on how to define your dynamic 2D array. But this variant was not yet mentionned, so I put it for the records.

As the last dimension of your array is fixed, you could define your 2D array as follows:

int (*sArray)[2]; //multidimensional array that holds the scores of both players
...
sArray = (int(*)[2]) calloc (n, sizeof(int)*2);  // self explaining

In this way, all the elements will be stored contiguously (each n element of the allocated array, is 2 contiguous integers), without the need for an array to arrays.

The rest of your code remains identical. Except that you shoud address sArray[i][0] and ..[1] instead of [1] and [2] and free memory at the end. In C array indexing starts always from 0 and goes to size-1.

Of course, this approach is strictly limited to 2D arrays where the last dimension is fixed.

Live demo with addressing

Comments

0

Usually to fill a bidimensional array you will use two nested for loops. For example :

int array[2][3] = {0};

for (i = 0; i < 2; i++)
   for (k = 0; k < 3; k++)
      scanf("%d", &array [i][k]);

Comments

0

You could do this too:

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

int main(int argc, const char * argv[]) {


    int n; //number of rounds
    int** sArray = malloc(2 * sizeof(int*)); //multidimensional array that holds the scores of both players
    scanf("%d", &n);
    sArray[0] = (int*)calloc(n , sizeof(int));
    sArray[1] = (int*)calloc(n , sizeof(int));

    int i;
    for (i = 0; i < n; i++) {
        scanf("%d %d", &sArray[0][i], &sArray[1][i]);
    }

    free(sArray[0]);
    free(sArray[1]);
    free(sArray);

    return 0;
}

3 Comments

That is somewhat of a painful way to allocate that does not quite accomplish what you have set out to do. Look closely at the comment for how to allocate a pointer-to-array 2 of type int or at the other answer to allocating a pointer-to-pointer-to type int.
@DavidC.Rankin: Got it!
Uh, this is UB. You want to read n before passing it to calloc.

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.