Как внутри структуры определить массив (динамический) структур того же типа, что и сама структура? - PullRequest
1 голос
/ 17 августа 2010

Цель состоит в том, чтобы построить «бесконечное» дерево с использованием динамических массивов.

items[3]
- MENUITEM
  - items[2]
    - MENUITEM
      -items[0]
    - MENUITEM
      - items[0]
- MENUITEM
  - items[0]
- MENUITEM
  - items[2]
    - MENUITEM
      - items[0]
    - MENUITEM
      - items[0]

Я определяю структуру:

typedef struct MENUITEM {
    char id, count;
    char *description;
};

И я могу динамически распределять элементы с помощью:

char count;
MENUITEM items[], *items_ptr;

count++;
realloc( items_ptr, count * sizeof(struct MENUITEM) );

Проблема в том, что внутри структуры я не могу снова назначить саму структуру, например:

typedef struct MENUITEM {
    char id, count;
    char *description;

    MENUITEM items[], *items_ptr;
};

Компилятор выводит: error: поле 'items' имеет неполный тип;что я тут не так делаю?Спасибо за любую предоставленную помощь.

Ответы [ 2 ]

1 голос
/ 17 августа 2010

Вам нужно использовать struct MENUITEM *items_ptr;. Обратите внимание на использование слова struct.

Почему у вас MENUITEM items[]? Это ни для чего не используется.

Сделайте это вместо:

typedef struct MENUITEM {
    char id, count;
    char *description;

    struct MENUITEM *items;
} MENUITEM;

void foo() {
    MENUITEM *root = (MENUITEM*)malloc(sizeof(MENUITEM));

    root->id = 87;
    root->count = 5;

    root->items = (MENUITEM*)malloc(sizeof(MENUITEM)*root->count);
}
0 голосов
/ 17 августа 2010

Измените структуру MenuItem, чтобы держать указатель на MENUITEM

typedef struct MENUITEM {
    char id, count;
    char *description;

    MENUITEM *items_ptr;
};

Не единственное, что распределение не является хорошим - это будет намного медленнее

count++;
realloc( items_ptr, count * sizeof(struct MENUITEM) );

Лучше было бы выделить блок памяти, скажем, для хранения 50 записей, когда предел достигнут, realloc это с удвоенным размером блока, и, пожалуйста, убедитесь, что вы не засоряете результат следующим образом:

Правильно:

MENUITEM *temp_items_ptr;
temp_items_ptr = realloc( items_ptr, count * sizeof(struct MENUITEM) );
if (temp_items_ptr != NULL){
   items_ptr = temp_items_ptr;
}else{
   /* Handle the out of memory situtation */
}

Неправильно:

items_ptr = realloc( items_ptr, count * sizeof(struct MENUITEM) );

Неправильный подход - это рецепт катастрофы и поздороваться с просочившейся памятью!

...