Other answers are flawless and explain everything perfectly, but I'd like to show you a more practical example since you can have so much fun by playing with C. Have a look at this:
Memory address array1: 0x7ffd58160dea
Memory address array2: 0x7ffd58160de5
Content of array1: 0123456789�
Content of array2: abcde0123456789�
Memory address] Memory content:
0x7ffd58160de5] a
0x7ffd58160de6] b
0x7ffd58160de7] c
0x7ffd58160de8] d
0x7ffd58160de9] e
0x7ffd58160dea] 0
0x7ffd58160deb] 1
0x7ffd58160dec] 2
0x7ffd58160ded] 3
0x7ffd58160dee] 4
0x7ffd58160def] 5
0x7ffd58160df0] 6
0x7ffd58160df1] 7
0x7ffd58160df2] 8
0x7ffd58160df3] 9
0x7ffd58160df4]
0x7ffd58160df5]
Let's consider 2 char arrays array1
and array2
with different lengths and without the terminator character '\0'
.
The following code saves the lowest address of the two arrays ((char*)&array1 < (char*)&array2
) and saves it in startingPtr
, then prints the following 100 char
(byte) of memory starting from startingPtr
, showing both the address and the content:
#include <stdio.h>
int main()
{
char array1[10] = "0123456789";
char array2[5] = "abcde";
char* startingPtr;
printf("Memory address array1: %p\nMemory address array2: %p\n", &array1, &array2);
printf("\nContent of array1: %s\nContent of array2: %s\n", array1, array2);
// Get which one has the lower address
if ((char*)&array1 < (char*)&array2)
startingPtr = (char*)&array1;
else startingPtr = (char*)&array2;
// Print memory content, starting from the memory address of the first array
printf("\nMemory address] Memory content:\n");
for (int i = 0; i < 100; i++)
{
printf("%p] %c\n", &(*(startingPtr + i)), *(startingPtr + i));
}
return 0;
}
Check the output there, with different compilers:
As you can notice, the output can be different for a bunch of reasons (depending on the compiler, the machine, virtual memory, etc.).
But the reason you can sometimes see the content of both the arrays is that it can happen that the Operating System allocates their variables near, in continuous memory addresses. Therefore printf("%s");
, which expects an adequately formatted "string" (i.e. a char buffer with the terminator character at the end), believes that your buffer is longer than 10 or 5 characters, and prints also the following characters.
However, that's definitely not reliable, since it's undefined behaviour.
NB: the notation *(array + index)
is one of the many ways you can access array elements. Since arrays are basically pointers to their first element, that means "get the value stored at memory address array + index", and is equivalent to array[index]
.