Если вы хотите сохранить использование тройного указателя, хранилище может быть выделено в стеке и инициализировано следующим образом:
char ***matrix;
char **mats_[2];
char *mat_rows_[2][ROWS+2];
char mat_cols_[2][ROWS+2][COLS+2];
matrix = &mats_[0];
for (int i = 0; i < 2; i++) {
matrix[i] = &mat_rows_[i][0];
for (int j = 0; j < ROWS+2; j++) {
matrix[i][j] = &mat_cols_[i][j][0];
memset(matrix[i][j], (int)DEFAULT, COLS+2);
}
}
Вы также можете определить matrix
как массив [2] из char **
вместо одного char ***
, что позволило бы исключить переменную mats_
:
char **matrix[2];
char *mat_rows_[2][ROWS+2];
char mat_cols_[2][ROWS+2][COLS+2];
for (int i = 0; i < 2; i++) {
...
В комментариях ниже OP спросил, нужен ли memset
. Все элементы mat_cols_[2][ROWS+2][COLS+2]
должны быть установлены в одно и то же значение DEFAULT
. Если DEFAULT
можно заменить на 0
, это легко сделать, определив mat_cols_
с помощью инициализатора со всем, по умолчанию равным 0:
char mat_cols_[2][ROWS+2][COLS+2] = { 0 };
Если DEFAULT
нельзя заменить на 0, единственный способ сделать это состоял бы в том, чтобы инициализатор предоставил значения для всех элементов в явном виде, что имеет проблему с удобством сопровождения, поскольку размеры определены в терминах макросов ROWS
и COLS
. Компилятор GNU C (G CC) имеет расширение для обозначенных инициализаторов языка C, которое позволяет диапазону элементов массива инициализироваться одним и тем же значением. Это можно использовать следующим образом:
char mat_cols_[2][ROWS+2][COLS+2] =
{[0 ... 1] =
{[0 ... ROWS+2-1] =
{[0 ... COLS+2-1] = DEFAULT}
}
};