2

I am trying to create a global 2D array of integers in C, but I'm not really sure how to go about that. For a 1D array, you can simply put

int numbers[];

but obviously you cannot leave two brackets empty like

int numbers[][];

So how can i do this? I am not sure of an easy way.

Thanks!

Jon
  • 31
  • 1
  • 2
  • 1
    You can't declare `int numbers[];` without an initializer for the compiler to figure our how big it is. How are you planning on initializing the 2D array? – dbush Jun 30 '16 at 20:10
  • The two most common ways of doing this are to use a 1 dimensional array and then compute an index like `i + j*inner_len`, or to use an array of pointers or a pointer to a block of pointers. You can also do a pointer to unknown size arrays, but be careful if you do. You have to use parentheses like `int (*numbers)[];`, and then you can't really do `numbers[i]` because sizeof(int[]) is not the proper size of an inner array so you must either calculate the offsets differently or cast to the right complete type like `((int(*)[inner_len])numbers)[i]`. – hacatu Jun 30 '16 at 20:22
  • You can't do that with arrays. array length should be known at compile time. What you are looking for is a list of some sort. – Dumbo Jun 30 '16 at 20:36

2 Answers2

0

In order to construct a 2D array, the idea is to create a flattened 2D array (thus, a 1D array). This actually means that all the columns will be put horizontally, one after the other. You will need to compute an index in order to access the elements.

Let's say that your array will have N rows and M columns. You cannot declare it as :

int numbers[N][M];

What you can do is declare it as :

int numbers[N*M];

so your elements will be in the range [0, N*M-1]. Then, you can access any element of the array using the index :

i*M + j;       

where 0 <= i <= N-1 and 0 <= j <= M-1.


However, given that the size is unknown, I would suggest that you use dynamic memory allocation instead of a 2D array. You can do this as following. First, declare a pointer to pointer, which will actually be a pointer to the first element of your 2D array :

int **numbers;

Then, allocate memory for the 2D structure :

int i;
numbers = malloc( N*sizeof(int *) );        // N is the number of the rows
if (numbers == NULL)
    return;
for (i = 0 ; i < N ; i++)
{
    numbers[i] = malloc( M*sizeof(int) );     // M is the number of the columns
    if (numbers[i] == NULL)
        return;
}

You can read more about dynamic memory allocation for 2D arrays here, in order to understand what happens in memory.


Finally, based on your question let me note that you can't declare :

int numbers[]; 

as the compiler needs an indication to know the size.

Marievi
  • 4,951
  • 1
  • 16
  • 33
  • malloc returns a void pointer, you are required to cast the malloc to the pointer type you want, if the compiler is not that smart. – Dumbo Jun 30 '16 at 22:00
  • 1
    @SaeidYazdani see this link on why not to cast the result of `malloc` : http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – Marievi Jul 01 '16 at 15:11
  • Well good to know. it might not cause problem. But I'll continue casting the malloc result anyways! – Dumbo Jul 01 '16 at 18:22
  • best to not teach poor coding habits. I.E. the answer should be checking (!=NULL) the returned value from a call to any memory allocation function (calloc, malloc, realloc) before using that pointer. – user3629249 Jul 02 '16 at 15:16
  • 1
    @user3629249 yes you are right, I had forgotten to add the check! Edited, thanks. – Marievi Jul 02 '16 at 19:45
-2

You will need a pointer to int for that purpose. C does not have a bultin 2D array, but you have ways to work around that. You have two options here:

Simulate a 2D array thru helper function

either you simulate the 2nd dimension; I suggest an helper function for that purpose, something like:

int getTwoDimensionArray(int ** array, int rowSize, int x, int y)
{
  return (*array)[x + y*rowSize];
}

void setTwoDimensionArray(int ** array, int rowSize, int x, int y, int value)
{
  (*array)[x + y*rowSize] = value;
}

Let say you want to allocate a 5x7 array dynamically, you would use those functions like such:

First allocate the 1D array:

int * myArray = (int*) malloc(5*7);

After, you would set value of 10 at position x=2, y=2 like that setTwoDimensionArray(&myArray, 5, 2, 2, 10);

And later, if you want to get back the value: int value = getTwoDimensionArray(&myArray, 5, 2, 2);

Have an array of arrays so simulate a 2D array

int getTwoDimensionArray(int ** array, int rowSize, int x, int y)
{
  return (*array)[x][y];
}

void setTwoDimensionArray(int ** array, int rowSize, int x, int y, int value)
{
  (*array)[x][y] = value;
}

Allocation of the array of array:

int ** myArray = (int**) malloc(5);
for ( int i=0; i<5; ++i )
{
  myArray[i] = (int*) malloc(7);
}

You would use the helper functions the same way you did with option #1

setTwoDimensionArray(&myArray, 5, 2, 2, 10);
int value = getTwoDimensionArray(&myArray, 5, 2, 2);

C++

Of course, if you can use C++, you have more options, see Multidimensional Containers in C++

Community
  • 1
  • 1
bass_dr
  • 17
  • 2
  • well, define unknown... if it is unknown at compile time, I agree it is not possible. It is possible though if the array size is provided at runtime. – bass_dr Jun 30 '16 at 20:42
  • unknown has a well definition...its is just simply unknown. BTW I didn't give that -1 – Dumbo Jun 30 '16 at 20:45