2015-07-19 4 views
3

Я хотел бы создать функцию C, которая принимает 2D-массив удвоений в качестве параметра и работает с этим массивом посредством индексации, например. printf("%f ", array[i][j]).Мне нужен простой пример передачи 2D-массива функции в C

То, что я был в состоянии собрать воедино из различных примеров и SO вопросы что-то вроде этого:

void printArray(double **array, int m, int n) 
{ 
    int i, j; 
    for (i = 0; i < m; i++) 
    { 
     for (j = 0; j < n; j++) 
     { 
      printf("%f ", array[i][j]); 
     } 
    printf("\n"); 
    } 
} 

В main, я в состоянии успешно напечатать массив следующим образом:

int i, j, k = 0, m = 5, n = 6; 
double **a = malloc(m * sizeof(*a)); 

//Initialize the arrays 
for (i = 0; i < m; i++) 
{ 
    a[i] = malloc(n * sizeof(*(a[i]))); 
} 
for (i = 0; i < m; i++) 
{ 
    for (j = 0; j<n; j++) 
    { 
     k++; 
     a[i][j] = k; 
    } 
} 

printArray(a, m, n); 

Однако, когда я пытаюсь инициализировать массив в некоторых заданных значений, а затем вызвать:

double a[5][6] = { { 1, 2, 3, 4, 5 ,6}, 
        { 1, 2, 3, 4, 5, 6}, 
        { 1, 2, 3, 4, 5, 6}, 
        { 1, 2, 3, 4, 5, 6}, 
        { 1, 2, 3, 4, 5, 6} }; 

printArray(a, 5, 6); 

Я встретился со следующей ошибкой:

Unhandled exception at 0x011514D3 in Example.exe: 0xC0000005: 
Access violation reading location 0xA1F8E3AC. 

Может кто-то объяснить, что моя ошибка и как ее исправить?

Обратите внимание, что в целях определения функции я буду знать размер массива во время выполнения, но не время компиляции. Кроме того, я собираюсь на Windows с VisualStudio 2013.

+0

Ваша функция, кажется, принимает двойной указатель, не передаете ли вы массив по значению? Попробуйте «& a» – Jay

+0

Если вы хотите, чтобы самый простой пример от другого пользователя на SO использовал: http://stackoverflow.com/questions/3911400/passing-2d-arrays. – KillaBytes

+0

@JohnColeman В printarray (a, 5, 6): 5,6 - это размер массива, а не элемент. Разве я не понял, что вы имели в виду? – ilent2

ответ

5

double a[5][6] имеет тип double[][6], что не совпадает с double**. double** - указатель на указатель на двойник. double[][6] - это тип данных, управляемых компилятором, который представляет собой двумерный массив.

Что здесь происходит, так это то, что созданный вами double[][6] был незаметно отлит в double** в вашем вызове printArray.

Если вы хотите взять double**, вам необходимо передать его double**. Вы можете инициализировать содержимое массива, заполнив каждый массив элементов отдельно:

 
double row1[3] = {3, 4, 5}; 
a[1] = row1; 

Это помогает решить эту проблему; потому что double[] хранится компилятором в виде смежного массива значений double, поэтому он неявным образом отбрасывает его до double*, как указано выше.

Другим решением является замена функции на «реальный» double[][6] вместо указателя указателя. Как вы это сделаете с массивами нефиксированного размера, зависит от вашего особого бренда C; насколько я знаю, это не часть стандарта C.

Третьим решением является построение массива по строкам с помощью malloc и заполнение его ячейкой по ячейке a[0][0] = 1 и так далее. У вас уже есть это в вашем вопросе, и он работает правильно.

Последнее, что нужно знать, это то, что вы выделяете a в стек: когда функция main завершается, доступ к ней приведет к неопределенному поведению.

+0

"type' double [] [] '" На языке C такого типа нет. При задании 'double a [5] [6]', 'a' имеет тип' double [5] [6] '. Это распадается на 'double (*) [6]', что эквивалентно 'double [] [6]' в прототипах функций. –

+0

@ н.м. Технически правильный, лучший тип правильного. В моем ответе я не хотел говорить «double [] [6]», потому что это исправляет шесть, и я был обеспокоен тем, что «double [] [x]' для произвольного x »будет путать вещи. Я укусил пулю и удалил ненужные разделы моего ответа. – Borealid

+0

Неверная неправильная дата в любое время недели. –

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