Typedef и сложное объявление в C - PullRequest
3 голосов
/ 03 ноября 2010

В связи с этим вопросом.

Что не так со следующим кодом?

typedef char (*p)[20] ptr;
ptr myFunction () {

    char sub_str[10][20]; 
    return sub_str;

} 

int main () {

    ptr str;
    str = myFunction();

}

Ответы [ 3 ]

8 голосов
/ 03 ноября 2010

синтаксически:
Изменение
typedef char (*p)[20] ptr;
К
typedef char (*ptr)[20];

Чтобы понять синтаксис объявлений typedef вроде этого. Представьте, что вы хотите переименовать тип T в тип U. Объявите переменную типа T с именем U и добавьте префикс объявления к typedef. Это все.

семантически:
Смотрите мои и другие ответы на ваш связанный вопрос. Это все еще неопределенное поведение

4 голосов
/ 03 ноября 2010

Вы возвращаете указатель на память, которая больше не будет существовать, когда myFunction () возвращает.

2 голосов
/ 03 ноября 2010

Основная проблема заключается в том, что substr является локальным по отношению к myFunction, и после выхода myFunction он больше не существует, поэтому возвращаемый вами указатель больше не будет действительным.

Во-вторых, вы не используете typedef правильно. Правильный синтаксис будет

typedef char (*ptr)[20];

Синтаксически, typedef в основном действует как спецификатор класса хранения, подобный static или extern (хотя семантика иная). По сути, вы выясняете объявление для объекта

char (*ptr)[20]; // ptr is a pointer to a 20-element array of char

и затем добавьте к нему typedef:

typedef char (*ptr)[20];

Каким-то образом myFunction необходимо выделить память таким образом, чтобы она не уничтожалась при выходе из функции. Вот один из вариантов:

typedef char (*ptr)[20];
ptr myFunction(size_t count)
{
  /**
   * Dynamically allocate a block of N 20-element arrays of char
   */
  ptr p = malloc(sizeof *ptr * count);
  return p;
}

int main(void)
{
  ptr str = myFunction(10);
  size_t i, j;

  for (i = 0; i < 10; i++)
    for (j = 0; j < 20; j++)
      str[i][j] = ...;
  ...
  free(str);
  return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...