Can I look at a two dimensional array as a one dimensional array of pointers, which the j index is a pointer to the array of the j row of the matrix?
For example if I have an array[4][4]. Is arr[2] the pointer to the second row array?
No. The data is continuous in memory.
arr[2] would know the size of a single array and add 2 times that to the array pointer to get to the appropriate offset.
I may be true... It is the case if you allocated it that way : How do I work with dynamic multi-dimensional arrays in C?. However, the best way to go may to use something like &arr[2][0]. Bye, Francis
Can I look at a two dimensional array as a one dimensional array of pointers, which the j index is a pointer to the array of the j row of the matrix?
Yes. But always remember that arrays are not pointers. In case of 2D array array[M][N], spaces are allocated for each of the array element array[i] (i is int here). But in case of array of pointers *array[M], you need to allocate space for each element of array.
For example if I have an array[4][4]. Is arr[2] the pointer to the second row array?
Yes. arr2 decays to the pointer to the row 2
Related
I am puzzled by the memory allocation and accesses to a matrix of pointers in an application I am working in.
There is a matrix defined as:
typedef double (*foo)[n/m][m][m];
Which I understand to be a three-dimensional matrix storing pointers to doubles. The memory allocation for all dimensions is done automatically.
Nonetheless, the following appears:
foo bar = (foo) malloc(sizeof(double) * n * n);
What exactly is this cast doing?. Furthermore, why do we need to allocate memory for these doubles?. I would think the matrix only contains pointers, which would later be initialized with the memory addresses of doubles declared separately.
Finally, I am, also confused by the way this matrix is accessed during its initialization:
bar[i/m][j/m][i%m][j%m] = value;
Where i and j are smaller than N. Mainly, I would like to know what the fourth index is adressing.
Thank you so much in advance for your help!
This double (*foo)[n/m][m][m] creates 1 single pointer foo that will be used to point to 3 dimensional arrays containing values of type double, where the size of each of the 3 dimensions are n/m, m and m respectively, for a total of (n/m)*m*m = n*m double values in each 3 dimensional array.
Note that you can use pointer's arithmetic over foo, so if foo points to one 3 dimensional array, then foo+1 will point to the next 3 dimensional array.
In pointer notation you would do (*(foo+1))[0][0][0] to access the first double value of the second 3 dimensional array, and you can rewrite this using array notation as foo[1][0][0][0] to do the same thing. So now you can see that by iterating over foo you are iterating over the 4th dimension of a 4 dimensional array.
From the code we see that it allocated n*n double values for this 4 dimensional array. So, as we don't know the size of the forth dimension, we could say that the dimensions of the array are something like [x][n/m][m][m] where x is the unknown size. But we do know that this 4 dimensional array will have n*n elements, so to find x we need to solve x*(n/m)*m*m = n*n, therefore x = n/m, and the dimensions are [n/m][n/m][m][m].
I have a dynamic array of double with 3 dimensions eg.
customArray : array of array of array of double
In the program I set the length of each dimension separately (not rectangular array) and change it when it is needed.
I wonder if the array is stored in a compact memory portion so to save it in a stream at once like writebuffer(customArray,sizeof(customArray))
and later, load it again to the same dynamic array like
readbuffer(customArray, savedSize);
Is this possible ?
This is not actually a multi-dimensional array. This is what is known as a jagged array. The inner most dimension is contiguous but the outer dimensions are arrays of pointers.
So the elements are not stored contiguously. If you wish to write them to a file in contiguous fashion you will need to arrange that by looping over each dimension.
In pseudo code that would be:
for i
for j
for k
write(arr[i,j,k]);
Since the innermost dimension is contiguous this could be written as:
for i
for j
write(arr[i,j]);
A jagged array can have member arrays of differing length but I presume that your array has members all of the same length.
In C we have two dimensional arrays, i.e. a[m][n].
In one dimensional arrays a is a pointer to the start of the array.
What about two dimensional arrays? Does a[i] hold a pointer to the start of the i row in an array? And thus a[i] is an array of pointers that is passed to a function in the following matter function(int **a, m, n)?
Does a[i] hold a pointer to the start of the i row in an array?
No. The data of a 2D array in C is a contiguous block of elements plus some clever indexing access. But a 2D array is an array of arrays, not an array of pointers.
Formally, the a[i] holds a 1D array. This may decay to a pointer to the first element of the ith row in certain contexts, but its type is still T[n], for some type T that you have not specified.
In one dimensional arrays a is a pointer to the start of the array.
Not correct. a is an array. When you use a in an expression, it "decays" into a pointer to the first element. To better understand this, read this chapter of the C FAQ, particularly this one.
What about two dimensional arrays? Does a[i] hold a pointer to the start of the i row in an array?
No. In a 2D array, a[i] is an array, while int a[x][y]; is an array of arrays. There are no pointers anywhere.
You might be confused because C allows this syntax: int a[][N] = ...;, but that syntax merely means that the size of the array of arrays depends on the number of items in the initialization list.
What's the difference between declaring multidimensional arrays like this:
int a[5][5];
or this
int* a[5];
?
Which one is better to use? Thanks.
Both may be used to declare 2-dimensional arrays.
In the first case, 25 int elements are allocated in a contiguous region in memory.
In this case the expression a[i][j] is translated by the compiler to *(a + i*5 + j).
The second one allocates 5 pointers to int. You can make it work as a two dimensional array by allocating vectors of int and making these pointers point to these vectors.
In this case a[i][j] means get the pointer that a[i] points to, then look up the 5th element in that vector. I.e. a[i][j] is translated to *(a[i] + j).
Note that in the second case, rows need not be of the same length.
int a[5][5]; says that the compiler should allocate enough memory to store 25 ints, and to treat it as a two-dimensional array called a.
int* a[5]; says that the compiler should allocate enough memory to store 5 pointers to integers, and treat it as an array of pointers called a. To actually use this as a two-dimensional array, you will have to allocate more memory and initialize those pointers to point at it. For example:
int * a[5];
for(int i = 0; i < 5; i++){ a[i] = malloc(sizeof(int) * 5); }
Without knowing your requirements it's hard to say which one is better for you. The second one allows you to efficiently swap two rows and is generally more flexible, but it takes more code to allocate and free the data structure.
The first one you are declaring bidimensional array (an array of arrays).
The second you're declaring an array of pointers to ints which can used as multidimensional array.
Is int *array[32] a pointer to an array of 32 ints, or an array of 32 pointers to int? Does it matter?
Take a look at http://www.cplusplus.com/doc/tutorial/arrays/ for declaring multidimensional arrays
Which is better apple or orange ?
this notation int a[ROWS][COLS]is used to create rectangular 2D array which dimensions are known at declaration time.
And this int * a[ROWS] notation is used when number of columns are unknown at 2D array declaration time OR number of columns can vary in run-time OR simply one wants to create non-rectangular (jagged) array like this:
1 2 3 4
4 6
7 1 1 1 5 6 7
9
Please look at this peice of code :-
#include<stdio.h>
int main()
{
int arr[2][2]={1,2,3,4};
printf("%d %u %u",**arr,*arr,arr);
return 0;
}
When i compiled and executed this program i got same value for arr and *arr which is the starting address of the 2 d array.
For example:- 1 3214506 3214506
My question is why does dereferencing arr ( *arr ) does not print the value stored at the address contained in arr ?
*arr is type integer array of length 2, so it shares the same address as arr. They both point to the beginning of their arrays, which is the same location.
in C, a 2d array is not represented in memory as an array of arrays; rather, it is a regular 1d array, in which the first given dimension is needed in order to calculate the right offset within the array at execution time. This is why in a multi-dimensional array you always need to specify all the dimensions except the last one (which is not required); for example, if you declare an array like
int a[2][3][4];
the array would be represented in memory as a single array of 2*3*4 elements in total. Trying to access the element at position (i,j,k), will actually be translated into accessing the element 3*i+4*j+k in the plain array. In some sense, the initial dimensions are needed to know where to put "row breaks" in the 1d array.