Когда вы делаете эту декларацию:
char main_map[ROWS][COLS+1]={
"a.bb",
"a.c.",
"adc.",
".dc."};
Вы создаете массив массивов символов. Массив char - это просто блок символов, а массив массивов - просто блок массивов, поэтому в целом main_map
- это целая куча символов. Это выглядит так:
| 'a' | '.' | 'b' | 'b' | 0 | 'a' | '.' | 'c' | '.' | 0 | ... | 'd' | 'c' | '.' | 0 |
Когда вы передаете main_map
в print_map()
, он оценивает main_map
как указатель на первый элемент массива - поэтому этот указатель указывает на начало этого блока памяти. Вы заставляете компилятор преобразовывать это в тип char **
.
Когда вы оцениваете map[0]
внутри функции (например, для первой итерации цикла), он выбирает значение char *
, на которое указывает map
. К сожалению, как вы можете видеть из ASCII-искусства, map
не указывает на char *
- он указывает на группу простых char
s. Там нет char *
значений там вообще. В этот момент вы загружаете некоторые из этих char
значений (4, 8 или другое число в зависимости от того, насколько велико char *
на вашей платформе) и пытаетесь интерпретировать их как char *
значение.
Когда puts()
затем пытается следовать этому поддельному char *
значению, вы получаете ошибку сегментации.