2016-01-22 2 views
19

я объявить двумерный массив как таковой:Variable два двумерный массив печати «подстрочный указателя к неполному типу» при обращении к

char arr[10][10]; 
arr[0][0] = 'X'; 

Теперь я печатаю в отладчике;

(lldb) po arr[0][0] 
'X' 

Awesome !! Нет проблем.

Теперь я объявить два двумерный массив, как, например:

int col = 10; 
int row = 10; 
char arr[row][col]; 
arr[0][0] = 'X'; 

Теперь я печатаю в отладчике;

(lldb) po arr[0][0] 
error: subscript of pointer to incomplete type 'char []' 
error: 1 errors parsing expression 

Почему?

+1

Я полагаю, что ни DWARF, ни gdb не поддерживают массивы переменной длины. – fuz

+2

'двойной массив как таковой:' означает? –

+3

@SouravGhosh «Двумерное массив вроде этого:» - это была моя интерпретация. Довольно запутанно, так как 'double' заставляет вас думать о поплавках. – unwind

ответ

17

отладчик не знает точно, насколько большой массив, поэтому вам нужно применить бросок:

(gdb) p ((char (*)[10])arr)[0][0] 
$2 = 88 'X' 
+0

Если бы это было 'arr [10] [3]' было бы нужно 'p ((char (*) [3]) обр) [0] [0] '? – sodiumnitrate

+0

@sodiumnitrate Правильно. Приведение должно соответствовать типу. – dbush

+0

Спасибо!Не могли бы вы объяснить, почему это не '((char (*) [10] arr) [0] [0]'? – sodiumnitrate

2

сделать именно col и row Const

const int col = 10; const int row = 10;

+0

Это вопрос на языке C. В C, что делает их' const' не будет делать В языке C 'const' на' col' и 'row' не будет препятствовать тому, чтобы массив стал VLA и, следовательно, не повлияет на исходную проблему. – AnT

13

Так dbush İŞ правильно. Но вот почему немного глубже.

char arr[10][10]; 

это не то же самое, как

char arr[row][col]; 

Несмотря на то, что они выглядят и действуют аналогично.

В стандарте C89 второй будет незаконным, поскольку компилятор не имеет представления о том, сколько места выделяется для переменной (даже если это определено в двух предыдущих строках).

Войдите в стандарт C99, и они представили что-то, называемое массивами переменной длины. Распределение пространства для массива определяется во время выполнения, а не во время компиляции. Теперь вы можете передать несколько переменных функции и объявить массив с размером, основанным на этих переменных. Ура!

Но это означает, что компилятор официально не знает подробностей о массиве. Как он большой. И LLDB использует компилятор Clang/LLVM, чтобы понять код.

Это пример того, как язык становится чуть более высоким и абстрагирует работу, выполняемую под капотом. И иногда это тебя укусы в задницу.

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