以下代码中的运行时错误

时间:2013-07-23 11:11:43

标签: c runtime-error

以下代码,根据我应该成功运行,但在运行时失败。我没有得到原因:

 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 个答案:

答案 0 :(得分:8)

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

例如,如果您查看数组arr,它在内存中就会显示

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

当你有指向指针p时,程序并不真正知道它指向一个数组数组,而是被视为一个指针数组,在内存中看起来像这样: / p>

+------+------+------+-----+
| p[0] | p[1] | p[2] | ... |
+------+------+------+-----+
  |      |      |
  |      |      v
  |      |      something
  |      v
  |      something
  v
  something

因此,当您执行p + 1时,您会转到p[1],这显然与arr[1]不同。

答案 1 :(得分:4)

使用

int **p=&m

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

然后,在地址中添加一个 - 一个内存地址,即不是指向下一个整数的字节数的一倍。

然后你尊重它两次:

  • 两个解除引用都将返回未指定的值,因此第二个取消引用可能会破坏您正在使用的操作系统的内存边界,
  • 两次都会偏离边界对齐,这可能会导致某些操作系统出现问题。

答案 2 :(得分:2)

int **p=&m;

p指向要放置m的地址:

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

现在,增加它:

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

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

答案 3 :(得分:0)

此处int **p=&m;p指向m。然后当p = p + 1; p指向m(整数)旁边的地址时。该地址可能无法访问。