如何在转换为int后取消引用指针**改变它指向的值?

时间:2012-11-27 11:20:34

标签: c pointers

#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将核心转储。这种行为的原因是什么?

4 个答案:

答案 0 :(得分:5)

current = *( (int**) current ) ;

首先,您将current转换为int**,因此从sizeof(int**)开始的&current字节中存储的值将被解释为{{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%的系统中,用户进程无法读取此地址。