0

以下代码,根据我应该成功运行,但在运行时失败。我不明白原因:

 void main()
 {
   int arr[5][3]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
   int *m=arr[0];
   int **p=&m;
   p=p+1;
   printf("%d",**p);

  }

a.exe 在 gcc 编译器,windows 7 64 位运行时停止工作

4

4 回答 4

8

数组数组和指向指针的指针完全不同,不能互换使用。

例如,如果您查看数组arr,它在内存中看起来像这样

+-----------+------------+------------+-----------+- ----+-----------+
| arr[0][0] | arr[0][1] | arr[0][2] | arr[1][0] | ... | arr[4][2] |
+-----------+------------+------------+-----------+- ----+-----------+

当您拥有指针到指针p时,程序并不真正知道它指向数组数组,而是将其视为指针数组,在内存中看起来像这样:

+------+------+------+------+
| p[0] | p[1] | p[2] | ... |
+------+------+------+------+
  | | |
  | | v
  | | 某物
  | v
  | 某物
  v
  某物

所以当你做的时候p + 1你得到p[1]的显然是不一样的arr[1]

于 2013-07-23T11:18:06.127 回答
4

随着线

int **p=&m

您创建一个指向整数指针的指针。

然后,你在地址上加一——一个内存地址,也就是不是指向下一个整数的字节数的一倍。

然后你尊重它两次:

  • 两个取消引用都将返回未指定的值,因此第二个取消引用可能会破坏您正在使用的操作系统的内存边界,
  • 两次都将超出边界对齐,这可能会导致某些操作系统出现问题。
于 2013-07-23T11:17:16.593 回答
2
int **p=&m;

p指向地址,m放置在哪里:

... |  m  | sth | ... |  p  | ...
       ^                 V
       |_________________|

现在,增加它:

... |  m  | sth | ... |  p  | ...
             ^           V
             |___________|

所以,现在p指向sth. 是什么sth?没人知道。但是您正试图访问sth包含的地址。这是未定义的行为。

于 2013-07-23T11:18:04.740 回答
0

在这里int **p=&m;p指向m. 那么当p = p + 1;p 会指向m(integer) 旁边的地址。该地址可能无法访问。

于 2013-07-23T11:17:51.810 回答