#include<stdio.h>
int main()
{
int *previous, *current ;
int a[5] = {1,2,3,4,5};
current =(int *) a ;
previous = current ;
current = *( (int**) current ) ; //my question is on this line
printf ("\nprevious is 0x%x and current is 0x%x \n ", previous , current ) ;
printf ("\nprev+1 0x%x , prev+4 0x%x \n", previous+1 , previous+4 ) ;
return 0;
}
,输出为:
bash-3.00$ ./a.out
previous is 0xffffd0f8 and current is 0x1
prev+1 0xffffd0fc , prev+4 0xffffd108
我的问题是:“current”之前指向数组的开头,然后再引用它并再次取消引用。以下语句如何更改“当前”的值?
current = *( (int**) current ) ;
另外,如果我打印*之前它将打印1,而* current将核心转储。这种行为的原因是什么?
答案 0 :(得分:5)
current = *( (int**) current ) ;
首先,您将current
转换为int**
,因此从sizeof(int**)
开始的¤t
字节中存储的值将被解释为{{1}的地址1}}。然后取消引用从演员表中获得的指针。这意味着,假定存储的int*
被跟踪,并且该地址的int**
字节存储在sizeof(int*)
中。
现在,current
指向数组current
的第一个元素,因此存储在a
开头的字节被复制到a
。如果current
,则sizeof(int*) == sizeof(int)
中存储的int
值1将被解释为地址。如果a[0]
(另一种常见事件),则指针值由两个sizeof(int*) == 2*sizeof(int)
s 1和2组成。
int
指向previous
的第一个元素,因此取消引用a
会产生值1.解除引用previous
现在尝试从地址读取current
1(它是未定义的行为,因此无论发生什么其他情况都不会违反标准,但这是正常的过程),这通常是无法访问的过程。
答案 1 :(得分:2)
current =(int *) a ;
将current
指向包含值1
的内存地址。因此
(int**) current
将此1
值本身视为指针,并且取消引用它会毫不奇怪地导致段错误。
答案 2 :(得分:1)
此
(int **) current
没有取消引用,而且
*(ptr)
没有引用。
取消引用
*current
引用
&(ptr)
最终声明:
current = &(*current);
答案 3 :(得分:0)
这很简单:你只是取消引用当前的,所以
*((int**) current)
是转换为int *的数组的第一个元素(0x1)。
取消引用0x1显然会导致段错误,因为在99.9%的系统中,用户进程无法读取此地址。