заполнить массив без callo c и mallo c in c? - PullRequest
0 голосов
/ 18 февраля 2020

У меня есть код, который выглядит как

int main(int argc, char *argv[]){
char ***matrix;
matrix = calloc(2, sizeof(char **));
for (int i=0; i<2; i++){
    matrix[i] = calloc(ROWS+2, sizeof(char*));
    for (int j=0; j<COLS; j++){
        matrix[i][j] = malloc(COLS+2);
        memset(matrix[i][j], (int)DEFAULT, COLS+2);
    }
}

Есть ли способ сделать подобное без использования mallo c и callo c? Например, в случае 1d массива я знаю, что вы можете сделать что-то вроде этого

unsigned char malloc_data[MAX_SIZE];
size_t malloc_used;  /* automatically initialized to zero */

void *stack_malloc(size_t size) {
void *p = &malloc_data[malloc_used];
if(size + malloc_used > MAX_SIZE) return 0;  /* out of memory */
malloc_used += size;
return p;
}

ИЛИ что-то вроде этого

static char *allocp = allocbuf[0];
if (allocbuf + ALLOCSIZE - allocp >= n) { /* it fits */ 

и

if (p >= allocbuf && p < allocbuf + ALLOCSIZE)

I хочу попробовать использовать переменные стека и временные переменные вместо динамически выделенных способов памяти. Однако, когда я пытаюсь подумать о том, как применить эти типы способов к моему трехмерному чувству, моя голова начинает кружиться. Пожалуйста, помогите разъяснить мне вещи

1 Ответ

0 голосов
/ 18 февраля 2020

Если вы хотите сохранить использование тройного указателя, хранилище может быть выделено в стеке и инициализировано следующим образом:

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}
        }
    };
...