-1

I'm writing a C for which I need to create a 2D array. I've found a solution to my problem using double pointers (pointers to pointers) in the following way:

#include <stdio.h>
#include <stdlib.h>
int d = 3;

#define DIM_MAX 9

void changeArray(int d, int *array[d]);

int main()
{
    //alocate array of 'd' colummns and 'd' row using malloc using array of pointers
    int **array = malloc(d*sizeof(int *));

    for(int count = 0; count < d; count++)
    {
        array[count] = malloc(d*sizeof(int *));
    }

    /* Call changeArray function */
    changeArray(d, array); 

    for(int i = 0; i < d; i++)
    {
        for(int j = 0; j < d; j++)
        {
            printf("%d ", array[i][j]);
        }
        printf("\n");
    }

    for(int count = 0; count < d; count++)
    {
        free(array[count]);
    }
    return 0;
}
void changeArray(int n, int *array[d])
{
    for(int i =0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            array[i][j] = i*j;
        }
    }
    return;
}

The code above works pretty well (it seems), but I've read in the web that using pointer to pointer is not the correct way to create 2D arrays. So I've come up with the following code, which also works:

#include <stdio.h>
#include <stdlib.h>
#define DIM_MAX 9
int d = 3;
void changeArray(int d, int *array[d]);

int main()
{
    //alocate array of 'd' colummns and 'd' row using malloc using array of pointers
    int *array[DIM_MAX] = {0};

    for(int count = 0; count < d; count++)
    {
        array[count] = (int *)malloc(d*sizeof(int *));
    }

    /* Call changeArray function */
    changeArray(d, array); 

    for(int i = 0; i < d; i++)
    {
        for(int j = 0; j < d; j++)
        {
            printf("%d ", array[i][j]);
        }
        printf("\n");
    }

    for(int count = 0; count < d; count++)
    {
        free(array[count]);
    }

    return 0;
}
void changeArray(int n, int *array[d])
{
    for(int i =0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            array[i][j] = i*j;
        }
    }
    return;
}

What is the difference in using any of the two ways above to write this code?

12
  • Just edited it. Thanks Commented Jul 28, 2017 at 18:12
  • 1
    I don't get why you don't simply write: int array[d][d]; Commented Jul 28, 2017 at 18:13
  • 5
    Neither of these is really a 2D array. The first one is a pointer to an array of pointers to arrays. The 2nd one is an array of pointers to arrays. int array[D1][D2] is a 2D array. Commented Jul 28, 2017 at 18:13
  • Any of these ways will work, but the key point is that when you pass an array to a function, it will automatically be demoted to a pointer to the first element, so once you go into an function that manipulates the array, the function will be working with pointers. Commented Jul 28, 2017 at 18:17
  • 1
    @Dale according to the ISO/IEC 9899:TC3, Section 6.7.8: Initialization, "3. The type of the entity to be initialized shall be an array of unknown size or an object type that is not a variable length array type.", consequentially int array[d][d]; results in error: variable-sized object may not be initialized. Commented Jul 28, 2017 at 18:41

3 Answers 3

0

[Not an answer, but an alternative approach to achieve the desired result, namely defining a user-defined 2D array.]

Assuming the compiler in use supports VLAs you could do this:

#include <stddef.h> /* for size_t */


void init_a(size_t x, size_t y, int a[x][y]); /* Order matters here!
                                                 1st give the dimensions, then the array. */
{
  for (size_t i = 0; i < x; ++i)
  {
    for (size_t j = 0; j < y; ++j)
    {
      a[i][j] = (int) (i * j); /* or whatever values you need ... */
    }
  }
}

int main(void)
{
  size_t x, y;

  /* Read in x and y from where ever ... */

  {
    int a[x][y]; /* Define array of user specified size. */

    init_a(x, y, a); /* "Initialise" the array's elements. */

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

2 Comments

That worked! Are there any downsides of using VLA's instead of what I was doing before? I mean, when should I use VLA's?
@Vinicius: Downsides? 1.) VLAs live on the stack, so size is limited. 2.) VLAs typical are not available from compilers <C99 and might not be available >=C11. They are not available in certain Non-C-Standard compliant C compilers and not all (?) in C++.
0

It is actually pretty simple. All you have to do is this:

int i[][];

You are overthinking it. Same as a normal array, but has two indexes.

1 Comment

But how do I pass this array as an argument for a function if I don't know the number of columns until the user enters it?
0

Let's say you want to create a "table" of 4 x 4. You will need to malloc space for 4 pointers, first. Each of those index points will contain a pointer which references the location in memory where your [sub] array begins (in this case, let's say the first pointer points to the location in memory where your first of four arrays is). Now this array needs to be malloc for 4 "spaces" (in this case, let's assume of type INT). (so array[0] = the first array) If you wanted to set the values 1, 2, 3, 4 within that array, you'd be specifying array[0][0], array[0][1], array[0][2], array[0][3]. This would then be repeated for the other 3 arrays that create this table.

Hope this helps!

Comments

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.