You might want to learn how these objects are laid out in memory:
int array[][3] = { {1,2,3}, {4,5,6}, {7,8,9} };
int *p_array = (int *) array;
This creates an object array
of type int[][3]
in memory (in this case stack) physically laid out in a hypothetical (16-bit word size) architecture as:
array 0x8000: 0x0001
0x8002: 0x0002
0x8004: 0x0003
0x8006: 0x0004
0x8008: 0x0005
0x800A: 0x0006
0x800C: 0x0007
0x800E: 0x0008
0x8010: 0x0009
p_array 0x8012: 0x8000
Where 0x8000
denotes the imaginary stack address of array
.
However, in your second example:
int array1[] = { 11, 12 };
int array2[] = { 13, 14, 15, 16 };
int array3[] = { 17, 18, 19 };
int *array_pointers[] = { array1, array2, array3 };
int *array_pointers2 = (int*) array_pointers;
Here array_pointers
is of type int *[]
which means it is a pointer to array of int
s. And the memory layout would be like the following:
array1 0x8000: 0x000B
0x8002: 0x000C
array2 0x8004: 0x000D
0x8006: 0x000E
0x8008: 0x000F
0x800A: 0x0010
array3 0x800C: 0x0011
0x800E: 0x0012
0x8010: 0x0013
and
array_pointers: 0x8012: 0x8000 address of array1
0x8014: 0x8004 address of array2
0x8016: 0x800C address of array3
array_pointers2: 0x8018: 0x8012 address of array_pointers
So when you try to print the contents of array_pointers2
, which now contain pointers to array of int
s, you will print the address values rather than the numbers they point to.
Here is an example that outputs the memory address of those objects:
Which prints:
array 0x7ffeda682090: 0x00000000000001
0x7ffeda682094: 0x00000000000002
0x7ffeda682098: 0x00000000000003
0x7ffeda68209c: 0x00000000000004
0x7ffeda6820a0: 0x00000000000005
0x7ffeda6820a4: 0x00000000000006
0x7ffeda6820a8: 0x00000000000007
0x7ffeda6820ac: 0x00000000000008
0x7ffeda6820b0: 0x00000000000009
p_array 0x7ffeda682038: 0x007ffeda682090
array1 0x7ffeda68204c: 0x0000000000000b
0x7ffeda682050: 0x0000000000000c
array2 0x7ffeda682060: 0x0000000000000d
0x7ffeda682064: 0x0000000000000e
0x7ffeda682068: 0x0000000000000f
0x7ffeda68206c: 0x00000000000010
array3 0x7ffeda682054: 0x00000000000011
0x7ffeda682058: 0x00000000000012
0x7ffeda68205c: 0x00000000000013
array_poin 0x7ffeda682070: 0x007ffeda68204c
0x7ffeda682078: 0x007ffeda682060
0x7ffeda682080: 0x007ffeda682054
array_poi2 0x7ffeda682040: 0x007ffeda682070
on my computer.
Source code for that in case external link expires:
#include <stdio.h>
#include <string.h>
int main(void)
{
int array[][3] = { {1,2,3}, {4,5,6}, {7,8,9} };
int *p_array = (int*) array;
for (int i = 0; i < 9; i++) {
printf("%-10s %08p: %016p\n", i == 0 ? "array" : "", &p_array[i], p_array[i]);
}
printf("%-10s %08p: %016p\n", "p_array", &p_array, p_array);
int array1[] = { 11, 12 };
int array2[] = { 13, 14, 15, 16 };
int array3[] = { 17, 18, 19 };
int *array_pointers[] = { array1, array2, array3 };
int *array_pointers2 = (int*) array_pointers;
putchar('\n');
for (int i = 0; i < sizeof(array1) / sizeof(array1[0]); i++) {
printf("%-10s %08p: %016p\n", i == 0 ? "array1" : "", &array1[i], array1[i]);
}
for (int i = 0; i < sizeof(array2) / sizeof(array2[0]); i++) {
printf("%-10s %08p: %016p\n", i == 0 ? "array2" : "", &array2[i], array2[i]);
}
for (int i = 0; i < sizeof(array3) / sizeof(array3[0]); i++) {
printf("%-10s %08p: %016p\n", i == 0 ? "array3" : "", &array3[i], array3[i]);
}
for (int i = 0; i < sizeof(array_pointers) / sizeof(array_pointers[0]); i++) {
printf("%-10s %08p: %016p\n", i == 0 ? "array_poin" : "", &array_pointers[i], array_pointers[i]);
}
printf("%-10s %08p: %016p\n", "array_poi2", &array_pointers2, array_pointers2);
return 0;
}
solved Why can I convert from int ** to int * in the case of the two-dimensional array, but not in the case of the array of pointers