Skip to content
Advertisement

Why this variable lies on same address

Here I have taken two local variables and printing the address of both. I am getting both addresses is same how?

code is here:

int main(int argc, char const *argv[])
{
    char str[150];
    char arr[][15]={0};
    printf("---str:[%p]---arr0:[%p]---arr1:[%p]n",str,arr[0],arr[1] );
}

and the output is:

cc tes.c 
root@asus-pc:~# ./a.out 
---str:[0x7fff669ac0a0]---arr0:[0x7fff669ac091]---arr1:[0x7fff669ac0a0]
root@asus-pc:~# 

here the str and arr[1] address are the same.

please help me out.

thank you in advance

Advertisement

Answer

In char arr[][15]={0};, the blank subscript leaves it to the compiler to calculate the number of elements. The single initial value initializes arr[0][15], after which the compiler sets the remaining elements of arr[0] to zero. Since there are no initializers for arr[1], the compiler sets the array size to 1 element, so arr[0] exists and arr[1] does not.

In the printf, arr[1] nominally refers to an array, so the compiler automatically converts it to a pointer to its first element, &arr[1][0]. While the behavior is not defined by the C standard, this nominally asks to compute where that element would be. Of course, if it existed, it would be immediately after the end of arr[0]. Since the compiler happened to place str just after arr, str is in the place that arr[1][0] would be, so the calculation produces the same address.

There are multiple reasons compiling and executing this same source code could produce different answers, including that the compiler may place str in a different location relative to arr and the fact that the behavior of using arr[1] is undefined means the compiler may transform it in unexpected ways during optimization.

However, the program can be changed to have (mostly) defined behavior by changing the printf to:

printf("---str:[%p]---arr0:[%p]---arr1:[%p]n",
    (void *) str, (void *) &arr[0], (void *) &arr[1]);

Although &arr[1] appears to refer to a non-existent object, C 2018 6.5.3.2 3 results in it being treated as arr+1, and 6.5.6 8 allows us to calculate the address just beyond the last element in an array. So the behavior of this printf is sufficiently defined that it will print the indicated addresses.

In that case, the address printed for str will equal the address printed for &arr[1] if str happens to follow arr in memory.

Advertisement