2013-07-23 5 views
0

Следующий код, по мне должен работать успешно, но терпит неудачу на runtime.I не получают причину:Ошибка выполнения в следующем коде

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 перестал работать во время выполнения в НКУ компилятор, окна 7 64 бит

+0

Возможно, вам понравится: [double pointer and arrays] (http://stackoverflow.com/questions/17752549/pointer-ptr-use/17752682#17752682) –

+3

Инициализация 2D-массива неверна. – AurA

+2

Как насчет всех предупреждений, которые вы игнорируете? –

ответ

4

с линии

int **p=&m 

создать указатель на указатель на целое число.

Затем вы добавляете один к адресу - один адрес памяти, то есть не один раз количество байтов, указывающих на следующее целое число.

Тогда вы почтительные дважды:

  • оба разыменовывает возвратят неопределенное значение, поэтому второе разыменование может нарушить границы памяти для операционной системы вы используете,
  • оба раза он будет с границей alignmemnt, что может вызвать проблемы в некоторых ОС.
0

Здесь int **p=&m;. p указывает на m. Затем, когда p = p + 1; p будет указывать на адрес рядом с m (целое число). Этот адрес может быть недоступен.

2
int **p=&m; 

p указывает на адрес, где m находится:

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

Теперь увеличиваем его:

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

Итак, теперь p указывает на sth. Что такое sth? Никто не знает. Но вы пытаетесь получить доступ к адресу sth. Это неопределенное поведение.

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 
    |  |  something 
    |  v 
    |  something 
    v 
    something 

так что, когда вы делаете p + 1 вы получите p[1], который явно не то же самое, как arr[1].

+0

Хороший ответ, от ascii-flow **? ** –

+2

@GrijeshChauhan Ха-ха, нет, все еще делаю это вручную :) –

+0

ему также нужно ответить предпочтительным способ объявить и инициализировать 2d-матрицу. Я думаю так. –

Смежные вопросы