Преобразовать указатель в двумерный массив символов в C - PullRequest
0 голосов
/ 17 апреля 2020

Возможно, это уже было задано, но я ничего не могу найти на нем.

У меня есть строковый массив, где количество строк в нем определяется во время выполнения (максимальная длина строки равна известно, если это поможет). Так как мне нужен глобальный доступ к этому массиву, я использовал указатель и малло c выделил для него достаточно места, когда я действительно знаю, сколько там уместится:

char *global_strings;

void some_func(int strings_nr, int strings_size)
{
    global_strings = (char*) malloc(strings_nr* strings_size* sizeof(char));
}

Что будет правильным способ C использовать этот указатель как двумерный массив символов, эквивалентный global_strings[strings_nr][strings_size]?

1 Ответ

1 голос
/ 17 апреля 2020

Как глобальный указатель на двумерные данные, чьи характеристики N * M определены во время выполнения, я бы порекомендовал вспомогательную функцию для доступа к строкам, а не для их непосредственного использования. Сделайте его inline или как макрос, если хотите.

char *global_strings = NULL;
size_t global_strings_nr = 0;
size_t global_strings_size = 0;

// Allocation -  
// OK to call again, but prior data may not be organized well with a new string_size
// More code needed to handle that.
void some_func(int strings_nr, int strings_size) {
  global_strings_nr = strings_nr;      // save for later use
  global_strings_size = strings_size;  // save for later use
  global_strings = realloc(global_strings,
      sizeof *global_strings * strings_nr * strings_size);
  if (global_strings == NULL) {
    global_strings_nr = global_strings_size = 0;
  }
}

// Access function
char *global_strings_get(size_t index)  {
  if (index >= global_strings_nr) {
    return NULL;
  }
  return global_strings + index*global_strings_size;
}

#define GLOBAL_STRINGS_GET_WO_CHECK(index) \
   (global_strings + (index)*global_strings_size)

Лучше использовать size_t для индексации и определения размера массива, чем int.

Приведение не требуется.

Расчеты памяти должны начинаться с size_t, а не int * int * size_t.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...