2013-09-05 7 views
0

Я получаю сегментирование здесь. Однако, если я объявляю массив как int ** и использую malloc, он отлично работает.Почему этот код не работает?

#include <stdio.h> 

void display(int **p,int numRows,int numCols) //Second Method// 
{ 
    printf("\n"); 
    int i,j; 
    for (i = 0; i< numRows;i++) 
    { 

     for (j = 0;j< numCols;j++) 
     { 
      printf("%d\t",p[i][j]); 
     } 
     printf("\n"); 
    } 
} 

int main() { 

    int arr[2][2]={{1,2},{4,5}}; 
     display(arr,2,2); 
} 

PS Мне не нужен альтернативный путь, просто скажите мне, почему этот код не работает.

+3

Вы видели предупреждения компилятора? – P0W

ответ

3

int** является указателем указатель, а int [2][2] смежно хранит два массива. Это твоя ошибка.

С int x[2][2], когда вы делаете x[1], вы сообщаете компилятору доступ к памяти, пропуская один набор из двух элементов, а результирующее выражение представляет собой массив из двух элементов. С int** x, когда вы делаете x[1], вы говорите компилятору, чтобы получить доступ к памяти, пропустив один указатель. Пока вы получаете доступ к данным одинаково для обоих, они просто не выкладываются одинаково.

В памяти x[2][2] = {{1, 2}, {4, 5}} выглядит следующим образом:

// 4 contiguous elements 
01 00 00 00 02 00 00 00 04 00 00 00 05 00 00 00 

Хотя int** x выглядит следующим образом:

// pointers to integers 
aa bb cc dd aa ab ac ad 
// At [aa bb cc dd]: 
    01 00 00 00 02 00 00 00 
// At [aa ab ac ad]: 
    04 00 00 00 05 00 00 00 

Поэтому, чтобы адаптировать для int**, вы должны создать массив int* указателей динамически и установите каждую запись в нижний размер вашего массива.

+0

Я вернусь к вам, ... потребуется некоторое время, чтобы получить все это. – rocker

6

arr представляет собой массив из 2 массивов из 2 int. Когда он используется в выражении, не являясь субъектом унарных операторов & или sizeof, он вычисляет указатель на его первый элемент.

Это «указатель на массив из 2 int», который является типом int (*)[2]. Номер редакции: Номер изображения: указан указателем поворота к int, являющимся int **. Кроме того, эти типы несовместимы, и вы не можете передать первое функции, ожидающей последнего.

int ** должен указывать на то, что само по себе является указателем. Указатель, который вы передаете в display, указывает на массив, а не на указатель.

+0

не arr также указывает на массив указателей, как p? – rocker

+0

@ user2714365: Нет, это не так. 'arr' * - массив массивов - нет указателей, это всего лишь блок из 4' int'. Когда вы передаете его функции, он вычисляет указатель, но этот указатель указывает на массив (первый из двух подмассивов в 'arr'). – caf

4

Пожалуйста, не пренебрегающие предупреждения

expected int **' but argument is of type 'int (*)[2]

arr представляет собой массив из 2 массивов 2 целых

Использование:

void display(int p[][2],int numRows,int numCols)

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