Home > Mobile >  What's the difference between defining 2d array: int *arr[ ] and int arr[ ][ ] in terms of how
What's the difference between defining 2d array: int *arr[ ] and int arr[ ][ ] in terms of how

Time:05-31

I've been trying to understand the difference between the two definitions and how to use them properly.
it seems to me that defining a 2d array with arr[length][width] stores the content of the matrix successively in the memory one row after the other (the matrix is essentially one big row) so that you can access the number in the i,j coordinates with this way : *(arr width*i j). And when sending it to a function the declaration can be func(int *arr) and you would have no problem accessing the matrix content because of how the 2d array is represented in the memory.

Whereas defining the array as int *arr[]; does not seem to store the content of the matrix in the memory in the same linear, successive way. the declaration of the function would have to be func(int **arr) or (int *arr[]). and while you can still access the matrix through coordinates i, j like this : arr[i][j], it doesn't seem possible to do it like this: *(arr width*i j). Am I correct in thinking its because defining the 2d matrix that way does not store the rows of the matrix successively in the memory or am I missing something?

CodePudding user response:

This declares a 2D array:

int arr1[100][200];

This declares a 1D array of pointers:

int *arr2[100];

They are not the same thing. arr1 contains 20000 ints, and arr2 contains 100 pointers.

arr1[20][30] will calculate the address of the 21st row, 31st column and go directly there. arr2[20][30] will calculate the address of the 21st pointer, read the pointer, calculate an address 30 ints away from where the pointer points to (so the 31st int if it points to an array of ints), and go there.

If you like, you can allocate space for 20000 ints, and you can save a pointer to each row inside arr2. Then both are usable for storing numbers in rows and columns.

The advantage of arr2 is that because each row has a pointer to the actual data, you can have different-sized rows, or overlapping rows, or missing rows. In arr1 the rows are exactly 200 ints long, no exceptions. The disadvantage of arr2 is that the computer has to do more work that it doesn't really need to do, i.e. it's slower. Another disadvantage of arr2 is that you still have to have a place to put the ints, so if your problem is to find a place to put ints, arr2 doesn't actually solve that.

CodePudding user response:

The declarations mean different things. Even though you can access (read/write) an integer by the same syntax, as x[y] is equivalent to *(x y).

int *a[] is a 1D array of pointers.

Each pointer can, but does not necessarily, point to a 1D array of integers. It can also be a null pointer or a pointer to a single integer.

If all pointers point to 1D arrays of integers, these arrays can be of different size.

Each 1D array, a as the array of pointers and each integer array that a pointer points to, has all of its elements consecutively in memory. But the locations of these 1D arrays are arbitrarily.

int a[][] is a 2D array of integers.

All the integers are consecutively in memory.

CodePudding user response:

If you have an array like this

int arr[length][width];

then this expression *(arr width*i j) to access elements of the array is incorrect at least because the expression has the type int[width] instead of int and in general when at least i is not equal to 0 will access memory beyond the array.

To access an element of the array you have to use the following expression *( *( arr i ) j ).

A function that deals with the array can be declared for example the following way

void f( size_t, size_t, arr[*][*] );

or to make the declaration more readable like

void f( size_t rows, size_t cols, arr[][cols] );

As for this array

int * arr[length];

that is a one-dimensional array where each element in turn points to a separate one-dimensional array then you may use the same expression *( *( arr i ) j ) to access the element of the array arr[i][j]. It is because the subscript operators are evaluated by this formula *( *( arr i ) j ).

The corresponding function can be declared like

void f( int * arr[], size_t rows, size_t cols );
  • Related