Printing a multidimensional array in C - c

I am trying to print a 2-D array in C by using pointers but I am not getting the expected output.
Program:-
#include <stdio.h>
int main()
{
int arr[2][3] = {{1,2,3},{4,5,6}};
int* p;
for ( p = arr; p <= arr+6; p++)
{
printf("%d ", *p);
}
return 0;
}
Output:-
1 2 3 4 5 6 -1116112128 1587637938 0 0 1893963109 32521 -1453950296 32766 -1453805568 1 800797033 21984 -1453949463
Could you tell me where I am wrong as the output should only be:
1 2 3 4 5 6

Could you tell me where I am wrong
The elements of arr are not integers, but arrays of 3 integers. So arr+6 is surely a different address than what you expect, since pointer arithmetic works in multiples of the size of the type in the array.
You'll always be better off using nested loops to iterate over a multidimensional array; treating it as one single-dimensional array of int leads to exactly the kinds of confusion you see here. The code is harder to understand and verify, it won't be any slower.

First, when looping through arrays of size n wth an index i, the condition for continuation should be i < n rather than i <= n, because array indexes in C run from 0 through n-1.
However, your code has a more serious error: 1-dimensional arrays can be 'decayed' into pointers to the elements' type; however, 2-dimensional arrays decay into pointers to 1-dimensional arrays. So, in your case, the type of the pointer used in the arr + 6 expression is a pointer to an array of three integers; further, when the 6 is added, that operation is performed in terms of the size of the pointed-to object, which is sizeof(int) * 3 – so, even when changing the <= to <, you will be running far beyond the actual bounds of the array.
To make the pointer arithmetic work in the correct 'units' (i.e. sizeof(int)), cast the arr to an int* before the addition (and also change the <= to <):
#include <stdio.h>
int main()
{
int arr[2][3] = { {1,2,3},{4,5,6} };
int* p;
for (p = (int*)arr; p < (int*)arr + 6; p++) {
printf("%d ", *p);
}
return 0;
}

You are trying to access the value in the wrong way, The two-dimensional array is saved as a continuous block in the memory. So, if we increment the value of ptr by 1 we will move to the next block in the allocated memory.
int arr[2][3] = {{1,2,3},{4,5,6}};
int *ptr = arr;
int i,j;
for (i = 0; i < 6; i++) {
printf("%d ", *(ptr + i));
}
return 0;

Array designators used in expressions with rare exceptions are implicitly converted to pointers to their first elements.
The type of the array elements of this array
int arr[2][3];
is int [3]. So a pointer to the first element of the array has the type int ( * )[3].
This assignment
p = arr;
where p has the type int * is incorrect because the operands of the assignment have incompatible pointer types.
At least you need to cast the right expression to the type int * like
p = ( int * )arr;
The same casting you need to use in the condition in the for loop. That is instead of
p <= arr+6
you have to write
p < ( int * )arr+6
Below there is a demonstration program that shows how to output a two-dimensional array as a two-dimensional array using pointers.
#include <stdio.h>
int main( void )
{
int arr[2][3] = {{1,2,3},{4,5,6}};
for ( int ( *p )[3] = arr; p != arr + 2; p++ )
{
for ( int *q = *p; q != *p + 3; ++q )
{
printf( "%d ", *q );
}
putchar( '\n' );
}
return 0;
}
If you want to output the two-dimensional array as a one-dimensional array then you can write
#include <stdio.h>
int main( void )
{
int arr[2][3] = {{1,2,3},{4,5,6}};
for ( int *p = ( int * )arr; p != ( int * )arr + 6; p++ )
{
printf( "%d ", *p );
}
putchar( '\n' );
return 0;
}

In
for ( p = arr; p <= arr+6; p++)
the expression arr, as an rvalue, is a pointer to the first element of the array (which is of type int [3], so each time you increment that pointer, it moves three int positions forward ---a whole row---, and so, arr + 6 points just after the sixth row of the array (if the array should ever had six rows) You can do it (with the proper explicit pointer conversions, as you are mixing pointers to int with pointers to int [3]) with the expression arr + 2 which is the addres of the first array element after the second row (and the number of rows of the array).
You can do it also declaring
int (*aux)[2][3] = &arr; /* aux is a pointer to the whole 3x2 array,
* so aux + 1 will be the position of the second
* 2D array after this one */
and then
int *end = (int *)(aux + 1);
or simply
int *end = (int *)(&arr + 1); /* see below */
(Beware that arr and &arr are both pointers and point to the same place, but they are not the same type (arr is of type int (*)[3] and &arr is of type int(*)[2][3])
So let's rewrite your code as
for (p = (int *)arr; p < end; p++)
or
for (p = (int *)arr; p < (int *)&arr + 1; p++)
would work, which seems more natural to do the calculus in complete array units than in rows or single cells (and you can change freely the dimensions of the array)
Your code would be:
#include <stdio.h>
int main()
{
int arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
int *end = (int *)(&arr + 1); /* try to avoid evaluating this expression in the loop
* despite that it can be optimized to comparing
* with a constant value */
char *sep = "";
for (int *p = (int *)arr; p < end; p++)
{
printf("%s%d", sep, *p);
sep = ", ";
}
putchar('\n');
return 0;
}
(Beware that you have to use < operator and not <= as you don't want to print the value pointed by end, because it lies one place outside of the array)
Finally a note: this will work with true arrays, but not with function parameters declared as arrays, because they decay to pointers and then &arr is not a pointer to data the size of the array, but it is the address of the parameter itself, which points to the array somewhere else.

Related

Is this a correct way to define array of pointers to array?

Is this a correct way to define array of pointers to array in C programming language?
int* ptr[2];
int n1[5] = { 2,3,4,5,6 };
int n2[5] = { 2,3,4,5,6 };
ptr[0] = &n1;
ptr[1] = &n2;
I am getting errors like:
epi_2.c:20:12: warning: incompatible pointer types assigning to 'int *' from 'int (*)[5]' [-Wincompatible-pointer-types]
ptr[1] = &n2;
You have to write
ptr[0] = n1;
ptr[1] = n2;
Array designators used in expressions with rare exceptions are converted to pointers to their first elements.
That is in the above statements expressions n1 and n2 have the type int * - the type of the left side expressions.
As for these statements
ptr[0] = &n1;
ptr[1] = &n2;
then the right side expressions have the type int ( * )[5] that is not compatible with the type int * of the left side expressions. So the compiler issues messages.
Otherwise you need to declare the array of pointers like
int ( * ptr[2] )[5];
//...
ptr[0] = &n1;
ptr[1] = &n2;
Here is a demonstration program.
#include <stdio.h>
int main( void )
{
int* ptr[2];
int n1[5] = { 2,3,4,5,6 };
int n2[5] = { 2,3,4,5,6 };
ptr[0] = n1;
ptr[1] = n2;
for ( size_t i = 0; i < 2; ++i )
{
for ( size_t j = 0; j < 5; j++ )
{
printf( "%d ", ptr[i][j] );
}
putchar( '\n' );
}
}
The program output is
2 3 4 5 6
2 3 4 5 6
And here is another demonstration program.
#include <stdio.h>
int main( void )
{
int ( * ptr[2] )[5];
int n1[5] = { 2,3,4,5,6 };
int n2[5] = { 2,3,4,5,6 };
ptr[0] = &n1;
ptr[1] = &n2;
for ( size_t i = 0; i < 2; ++i )
{
for ( size_t j = 0; j < 5; j++ )
{
printf( "%d ", ( *ptr[i] )[j] );
}
putchar( '\n' );
}
}
The program output is the same as shown above
2 3 4 5 6
2 3 4 5 6
Is this a correct way to define array of pointers to array?
&n1 does return a pointer to an array.
But ptr[0] is not a pointer to an array. It's a pointer to an int.
You have two options.
Change ptr[0] to be a pointer to an array
By using the following, ptr becomes an array of pointers to arrays of 5 ints.
int ( *ptr[2] )[5] = { &n1, &n2 };
Change &1n to something that returns a pointer to int
But we rarely deal with pointer to arrays. We usually work with pointers to the first element of the array.
int *ptr[2] = { &( n1[0] ), &( n2[0] ) };
Because an array degenerates into a pointer to its first element, the following is equivalent but shorter:
int *ptr[2] = { n1, n2 };
In both cases, you end up with a pointer to the same address. But the type of the pointer is different. About the only difference is that sizeof( *ptr[0] ) will vary.
#include <stdio.h>
int main( void ) {
int ( *ptrA[2] )[5];
int *ptrB[2];
printf( "%zu\n", sizeof( *ptrA[0] ) ); // 20, size of array of 5 `int`.
printf( "%zu\n", sizeof( *ptrB[0] ) ); // 4, size of one `int`.
}
In C, there are two kinds of pointers to arrays:
Pointers that point to the first element of the array.
Pointers that point to the array as a whole.
If you have an array
int arr[5] = { 2,3,4,5,6 };
then you can create a pointer to the first element of the array the following way:
int *ptr = arr;
In the line above, the expression arr will automatically decay to &arr[0], i.e. to a pointer to the first element of the array.
You can create a pointer to the array as a whole the following way:
int (*ptr)[5] = &arr;
In C, it is more common to use the first kind of pointer. However, which kind of pointer you want depends on the situation.
For example, do you want sizeof *ptr to evaluate to the size of the entire array? Or do you want that expression to evaluate to the size of a single element of the array?
Also, how do you want ptr++ to behave? Do you want the pointer jump to the next element of the array? Or do you want the pointer to jump over the entire array (for example because you are using an array of arrays and want to jump to the next element of the outer array)?
If you want sizeof *ptr to evaluate to the size of a single element and want ptr++ to jump to the next element of the array, then you want the first kind of pointer. However, if you want sizeof *ptr to evaluate to the size of the entire array and want ptr++ to jump over the entire array, then you want the second kind of pointer.
If in doubt, I recommend that you chose the first kind of pointer, because that kind of pointer is easier to handle and more common.
Once you have decided which kind of pointer you want, you can then create an array of these pointers.
If you want an array of the first kind of pointer, then you can define that array like this:
int *ptrs[2];
ptrs[0] = n1;
ptrs[1] = n2;
If you instead want an array of the second kind of pointer, then you can define that array like this:
int (*ptrs[2])[5];
ptrs[0] = &n1;
ptrs[1] = &n2;

How to assign Pointer to an Array, to a new Array?

I got this code:
#include <stdio.h>
#include <string.h>
int main(void)
{
int a[3]={1,2,3},
b[3];
int (*p)[3]= &a;
b = p;
for(int i=0;i<3;i++)
printf("%i",b[i]);
}
-I wanted output to be like "123", but I am having problems assigning the b array to what the p is pointing.
ps -
memcpy( b, p, sizeof(b)); does just what i want but i want to do it without the use of that function.
The line
b = p;
has a couple of problems. First of all, array expressions may not be the target of the = operator; you can't assign an entire array in a single operation like that1.
Secondly, the types don't match; p has type int (*)[3], while b has type int [3]. Arrays are not pointers - array expressions "decay" to pointer expressions under most circumstances, but in this case even the pointers would be of incompatible types (b would decay to an expression of type int *, not int (*)[3]).
No, the only ways to copy the contents of one array to the other are to use library functions like memcpy or to use a loop to assign each element individually:
for ( size_t i = 0; i < 3; i++ )
b[i] = (*p)[i]; // or b[i] = a[i]
That's it.
Initialization is different from assignment.
Arrays do not have the assignment operator. You need somehow to copy elements of one array to another array.
Without using the standard function memcpy you can use an ordinary loop as for example
for ( size_t i = 0; i < sizeof( a ) / sizeof( *a ); i++ )
{
b[i] = a[i];
}
Or if to use intermediate pointers you can write
for ( int *p = a, *q = b; p != a + sizeof( a ) / sizeof( *a ); ++p )
{
*q++ = *p;
}
You have a small fixed size array, perfectly suitable for wrapping inside a struct, so you can do this:
#include <stdio.h>
#include <string.h>
struct ia3 {
int data[3];
}
int main(void)
{
struct ia3 a = {{1,2,3}};
struct ia3 b;
struct ia3 *p = &a;
b = *p; // struct assignment
for(int i=0;i<3;i++) {
printf("%i",b.data[i]);
}
}
"...but i want to do it without the use of [memcpy(,,)]."
It is unclear why using memcpy() is not agreeable in this exercise, but it does do the task more efficiently then loop for large array sizes.
If you just want a pointer to the array...
int a[3] = {1,2,3};
//create pointer
int *b = a;//does not copy array a, just points to it
//If an additional array is needed, do this...
int b[3] = {0};
int i = 0;
//to copy, without memcpy(), use this alternative.
for(i=0; i<3; i++) b[i] = a[i];//makes copy of array a
for(i=0;i<3;i++)
printf("%i", b[i]);

How to use pointer to bidimensional array C

How do I edit a value in an array with pointer in C?
int *pointer;
int array[3][1];
I tried this:
int *Pointer
int array[2][2];
Pointer[1][1]= 6;
but when compiling, I get a segmentation fault error. What to do?
Given some array int Array[Rows][Columns], to make a pointer to a specific element Array[r][c] in it, define int *Pointer = &Array[r][c];.
Then you may access that element using *Pointer in an expression, including assigning to *Pointer to assign values to that element. You may also refer to the element as Pointer[0], and you may refer to other elements in the same row as Pointer[y], where y is such that 0 ≤ y+c < Columns, i.e., Pointer[y] remains in the same row of the array.
You may also use Pointer[y] to refer to elements of the array in other rows as long as none of the language lawyers see you doing it. (In other words, this behavior is technically not defined by the C standard, but many compilers allow it.) E.g., after Pointer = &Array[r][c];, Pointer[2*Columns+3] will refer to the element Array[r+2][c+3].
To make a pointer you can use to access elements of the array using two dimensions, define int (*Pointer)[Columns] = &Array[r];.
Then Pointer[x][y] will refer to element Array[r+x][y]. In particularly, after int (*Pointer)[Columns] = &Array[0]; or int (*Pointer)[Columns] = Array;, Pointer[x][y] and Array[x][y] will refer to the same element.
You can access any given element with this syntax: array[x][y].
By the same token, you can assign your pointer to any element with this syntax: p = &array[x][y].
In C, you can often treat arrays and pointers as "equivalent". Here is a good explanation:
https://eli.thegreenplace.net/2009/10/21/are-pointers-and-arrays-equivalent-in-c
However, you cannot treat a simple pointer as a 2-d array. Here's a code example:
/*
* Sample output:
*
* array=0x7ffc463d0860
* 1 2 3
* 4 5 6
* 7 8 9
* p=0x7ffc463d0860
* 0x7ffc463d0864:1 0x7ffc463d0868:2 0x7ffc463d086c:3
* 0x7ffc463d0870:4 0x7ffc463d0874:5 0x7ffc463d0878:6
* 0x7ffc463d087c:7 0x7ffc463d0880:8 0x7ffc463d0884:9
*/
#include <stdio.h>
int main()
{
int i, j, *p;
int array[3][3] = {
{1,2,3},
{4,5,6},
{7,8,9}
};
// Dereference 2-D array using indexes
printf("array=%p\n", array);
for (i=0; i < 3; i++) {
for (j=0; j < 3; j++)
printf ("%d ", array[i][j]);
printf ("\n");
}
// Dereference 2-D array using pointer
p = &array[0][0];
printf("p=%p\n", p);
for (i=0; i < 3; i++) {
for (j=0; j < 3; j++)
printf ("%p:%d ", p, *p++);
printf ("\n");
}
/* Compile error: subscripted value p[0][0] is neither array nor pointer nor vector
p = &array[0][0];
printf("p=%p, p[0]=%p, p[0][0]=%p\n", p, &p[0], &p[0][0]);
*/
return 0;
}
Cast the 2D-array into 1D-array to pass it to a pointer,
And then, You are ready to access array with pointer. You can use this method to pass 2D-array to a function too.
#include <stdio.h>
int main()
{
int arr[2][2];
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
arr[i][j] = (2 * i) + j;
}
}
int *Pointer = (int *)arr; // Type conversion
/*
&arr[0][0] = Pointer + 0
&arr[0][1] = Pointer + 1
&arr[1][2] = Pointer + 2
&arr[2][2] = Pointer + 3
Dereference Pointer to access variable behind the address
*(Pointer + 0) = arr[0][0]
*(Pointer + 1) = arr[0][1]
*(Pointer + 2) = arr[1][2]
*(Pointer + 3) = arr[2][2]
*/
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
printf("%d ", *(Pointer + (2 * i) + j)); // Accessing array with pointer
}
printf("\n");
}
return 0;
}
Using the function wv_matalloc from https://www.ratrabbit.nl/ratrabbit/content/sw/matalloc/introduction , you can write the following code:
#include <stdio.h>
#include "wv_matalloc.h"
int main()
{
double **matrix;
int m = 3;
int n = 4;
// allocate m*n matrix:
matrix = wv_matalloc(sizeof(double),0,2,m,n);
// example of usage:
int i,j;
for (i=0; i<m; i++)
for (j=0; j<n; j++)
matrix[i][j] = i*j;
printf("2 3: %f\n",matrix[2][3]);
}
Compile with:
cc -o main main.c wv_matalloc.c
1.
You never assigned a value to Pointer in your example. Thus, attempting to access array by Pointer invokes undefined behavior.
You need to assign Pointer by the address of the first element of array if the pointer shall be a reference:
Pointer = *array;
2.
You can't use 2D notation (p[1][1]) for a pointer to int. This is a C syntax violation.
3.
Since rows of static 2D arrays are allocated subsequent in memory, you also can count the number of array elements until the specific element of desire. You need to subtract the count by 1 since indexing start at 0, not 1.
How does it work?
Each row of array contains 2 elements. a[1][1] (the first element of the second row) is directly stored after the first two.
Note: This is not the best approach. But worth a note beside all other answers as possible solution.
#include <stdio.h>
int main (void)
{
int *Pointer;
static int array[2][2];
Pointer = *array;
Pointer[2] = 6;
printf("array[1][1] (by pointer) = %d\n", Pointer[3]);
printf("array[1][1] (by array istelf) = %d\n", array[1][1]);
}
Output:
array[2][2] (by pointer) = 6
array[2][2] (by array istelf) = 6
Side Notes:
To address the first element of the second row by array[1][2] invokes undefined behavior. You should not use this way.
"but when compiling, I get a segmentation fault error."
Segmentation fault error do not occur at compile time. They occur at run time. It just gives you the impression because high probably your implementation immediately executes the program after compilation.

what's *p when p is declared as int (*)[size] and assigned to an array

code:
int arr[5] = {1,2,3,4,5};
int (*p)[5] = &arr;
printf("p:%p\n",p);
printf("*p:%p\n",*p);
result: p = *p = arr = 0x7ffee517c830 they are all the address of the array
The right way to use p to visit arr[i] is *(*p+i)
The type of pointer p is int(*)[5], so p point to an array which type is int [5]. But we can't say that p point to an invisible shell of arr, p is a variable after all. It stores the address of arr, which is also the address of arr[0], the first element of arr.
I thought *p will get me 1, which is the first element of arr.
The dereference operation means take the value in p as address and get the value from this address. Right?
So p stores the address of arr,which is 0x7ffee517c830 here, and 1 is stored in this address. Isn't **p illegal? The first dereference give us 1, and second dereference will use 1 as address which is illegal.
What I am missing?
The result of *p is an lvalue expression of array type. Using (*p) is exactly the same as using arr in any expression you could now think of.
For example:
&*p means &arr
**p means *arr (which is legal).
(*p)[i] means arr[i].
sizeof *p means sizeof arr.
Arrays are not special in this regard. You can see the same phenomenon with int x; int *q = &x;. Now *q and x have exactly the same meaning.
Regarding your last paragraph, I think you are confusing yourself by imagining pointers as glorified integers. Some people teach pointers this way but IMO it is not a good teaching technique because it causes the exact confusing you are now having.
If you dereference an int(*)[5] you get an int[5] and that's all there is to it. The data type matters in dereferencing. It does not make sense to talk about "dereferencing 0x7ffee517c830". Again this is not peculiar to arrays; if you dereference a char ***, you get a char ** etc.
The only way in which arrays are "different" in this discussion is what happens if you try to do arithmetic on them, or output them, etc. If you supply an int[5] as a printf argument for example, there is implicit conversion to int * pointing at the first of those 5 ints. This conversion also happens when applying the * operator to an int[5], which is why you get an int out of that.
p is declared as a 'pointer to int[5]'.
arr is declared as an 'int[5]`
so the initializer p = &arr; is not really that strange. If you substituted any primitive type for int[5] you wouldn't bat an eye.
*p is another handle on arr. so (*p)[0] = 1.
This really only comes up in wierd cases. It's most natural where you dereference the pointer-to-array using the subscript operator. Here's a contrived example where I want to pass a table as argument.
#include <stdio.h>
int print_row_range(int (*tab) [2], int first, int last)
{
int i;
for(i=first; i<= last; i++)
{
printf("{%d, %d}\n", tab[i][0], tab[i][1]);
}
}
int main(int argc, char *argv[])
{
int arr[3][2] = {{1,2},{3,4},{5,6}};
print_row_range(arr,1,2);
}
This example treats the table as an array of rows.
Dereferencing doesn't give you a value. It gives you an object, which can be used as a value of its type if it can be converted to.
*p, being identical to arr, is an object of an array of 5 ints, so if you want to get an integer from the array, you must dereference it again like (*p)[3].
Consider a bigger example:
int arr[5][5];
int (*p)[5] = arr;
Now you get arr[0] with *p, which itself is an array of 5. Here comes the difference:
*( p+1) == arr[1];
*(*p+1) == arr[0][1];
^ ^^^
Got the point?
One use case is to be able to allocate with malloc an 2D (or more) pointer of arrays with only one malloc:
#include <stdio.h>
#include <stdlib.h>
static int (*foo(size_t n))[42] {
return malloc(sizeof *foo(0) * n);
// return malloc(sizeof(int [n][42]); works too
}
int main(void) {
size_t n = 42;
int (*p)[42] = foo(n);
if (!p) {
return 1;
}
printf("p:");
int accu = 0;
for (size_t i = 0; i < n; i++) {
for (size_t j = 0; j < sizeof *p / sizeof **p; j++) {
p[i][j] = accu++;
printf(" %d", p[i][j]);
}
}
printf("\n");
free(p);
}
I think this very funny.
One more with VLA:
#include <stdio.h>
#include <stdlib.h>
static void *foo(size_t elem, size_t n, size_t m) {
return malloc(elem * n * m);
}
int main(void) {
size_t n = 42;
int (*p)[n] = foo(sizeof **p, n, n);
if (!p) {
return 1;
}
printf("p:");
int accu = 0;
for (size_t i = 0; i < n; i++) {
for (size_t j = 0; j < sizeof *p / sizeof **p; j++) {
p[i][j] = accu++;
printf(" %d", p[i][j]);
}
}
printf("\n");
free(p);
}

Can I declare a pointer to a 2d array before I know the dimensions?

I know that one way to declare a pointer to a 2d array is like this:
int(*p)[100];
Then after assigning it to something, I can use elements like this:
p[1][6] = 18;
But let's say I don't yet know the dimensions of the array and I intend to malloc them when I find out.
One solution is that I declare a pointer to just an int, then use pointer arithmetic to navigate the array. I usually do this, but this time I'd like to use the square bracket notation for convenience.
So how do I declare this pointer when I don't yet know the dimensions and I intend to use square bracket notation?
So how do I declare this pointer when I don't yet know the dimensions and I intend to use square bracket notation?
You can use a pointer to a pointer.
int** p = NULL;
and later....
p = malloc(N*sizeof(int*));
for (int i = 0; i < N; ++i )
{
p[i] = malloc(M*sizeof(int));
}
and make sure to deallocate in multiple steps.
for (int i = 0; i < N; ++i )
{
free(p[i]);
}
free(p);
Another way.
// Allocate memory for the pointers.
p = malloc(N*sizeof(int*));
// Allocate memory for the ints.
p[0] = malloc(M*N*sizeof(int));
// Assign the values to the elements of p.
for (int i = 1; i < N; ++i )
{
p[i] = p[i-1] + M;
}
and deallocate in only two steps.
free(p[0]);
free(p);
Simply use a pointer to a variable length array.
Your sizes, y rows with x elements:
size_t x = 123;
size_t y = 30;
Allocate in with one call, sizeof(*p) is identical to sizeof(int) * 123:
int (*p)[x] = malloc( sizeof(*p) * y );
And iterate the 2d array:
for( size_t i = 0 ; i < y ; i++ )
for( size_t j = 0 ; j < x ; j++ )
p[i][j] = 0;
int(*p)[100];
This is not you want . This is pointer to array of int.
What you want is pointer to pointer to int.
int **p;
p=malloc(sizeof(int *)*r); // allocate memory for r number of int *
for(int i=0;i<r;i++)
p[i]=malloc(sizeof(int)*c); // allocate memory to each pointer
free in similar manner.
To index an array of arrays rather than an array of pointers, you can use this trick:
#include <stdlib.h>
#include <stdio.h>
void f( const size_t m, const size_t n, const char s[m][n] )
{
printf( "%s, %s!\n", s[0], s[1] );
return;
}
int main(void) {
static const char hello[][6] = { "hello", "world" };
f( sizeof(hello)/sizeof(hello[0]), sizeof(hello[0]), hello );
return EXIT_SUCCESS;
}
Your question is tagged C and not C++, but C++ does have references to arrays: int (&foo)[m][n] = bar;

Resources