简体   繁体   English

为什么这个变量位于同一个地址

[英]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: output 是:

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.这里 str 和 arr[1] 地址是相同的。

please help me out.请帮帮我。

thank you in advance先感谢您

In char arr[][15]={0};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.单个初始值初始化arr[0][15] ,之后编译器将arr[0]的剩余元素设置为零。 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.由于arr[1]没有初始值设定项,编译器将数组大小设置为 1 个元素,因此arr[0]存在而arr[1]不存在。

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] .printf中, arr[1]名义上指的是一个数组,因此编译器会自动将其转换为指向其第一个元素&arr[1][0]的指针。 While the behavior is not defined by the C standard, this nominally asks to compute where that element would be.虽然 C 标准没有定义该行为,但这名义上要求计算该元素的位置。 Of course, if it existed, it would be immediately after the end of arr[0] .当然,如果它存在,它将立即在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.由于编译器恰好将str放在arr之后,因此str位于arr[1][0]的位置,因此计算产生相同的地址。

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.编译和执行相同的源代码可能会产生不同的答案有多种原因,包括编译器可能将str放置在相对于arr的不同位置以及使用arr[1]的行为未定义这一事实意味着编译器可能会对其进行转换在优化过程中以意想不到的方式。

However, the program can be changed to have (mostly) defined behavior by changing the printf to:但是,可以通过将printf更改为:

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.虽然&arr[1]似乎指的是不存在的 object, C 2018 6.5.3.2 3 导致它被视为arr+1 ,而 6.5.6 8 允许我们计算数组中最后一个元素之外的地址. So the behavior of this printf is sufficiently defined that it will print the indicated addresses.所以这个printf的行为被充分定义,它将打印指示的地址。

In that case, the address printed for str will equal the address printed for &arr[1] if str happens to follow arr in memory.在这种情况下,如果str恰好跟在 memory 中的arr后面,则为str打印的地址将等于为&arr[1]打印的地址。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM