2
#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 ) ;

此外,如果我打印 *previous 它将打印 1 而 *current 将核心转储。这种行为的原因是什么?

4

4 回答 4

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

首先,您current转换为 an int**,因此存储在sizeof(int**)从 at 开始的字节中的值&current将被解释为 an 的地址int*。然后你取消引用从强制转换中获得的指针。这意味着,int**假设存储在那里,并且该sizeof(int*)地址处的字节存储在current.

现在,current指向数组的第一个元素a,因此存储在开头的字节a被复制到current. 如果sizeof(int*) == sizeof(int),则int存储的值 1a[0]被解释为地址。if sizeof(int*) == 2*sizeof(int)(另一种常见的情况),那么指针值是由两个ints 1 和 2 组成的。

previous指向 的第一个元素a,因此解引用previous产生值 1。解引用current现在尝试int从地址 1 读取一个(这是未定义的行为,所以无论发生什么其他事情都不会违反标准,但这是正常的过程),该过程通常无法访问。

于 2012-11-27T11:26:09.320 回答
2
current =(int *) a ;

current指向包含值的内存地址1。所以

(int**) current

将此1值本身视为一个指针,并且取消引用会毫无疑问地导致段错误。

于 2012-11-27T11:26:10.147 回答
1

(int **) current

不是取消引用,这

*(ptr)

不是参考。

取消引用

*current

参考

&(ptr)

最后声明:

current = &(*current);
于 2012-11-27T11:40:48.540 回答
0

这很简单:你只是取消引用当前,所以

*((int**) current)

是数组的第一个元素(即 0x1)转换为 int*。

取消引用 0x1 显然会导致段错误,因为在 99.9% 的系统中,用户进程无法读取此地址。

于 2012-11-27T11:30:15.167 回答