C - Использование объединения, выделение памяти

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

typedef struct event_queue{
Event* event;
int size;
int front;
int count;
int delay;
} event_queue;

Это базовая круговая очередь. Значение события представляет собой массив EventPointers, и он проходит каждый X раз, чтобы исключить одно из событий из очереди. Он инициализирован как

p->event = calloc(p->size, sizeof(Event));

Дело в том, что я хочу сделать аналогичную очередь с аналогичной функциональностью, чтобы ставить в очередь похожие события другого типа, но с немного другими данными. Изначально я просто хотел иметь отдельные очереди и проходить их по отдельности, но функциональность настолько повторяется, что кажется, что я просто делаю это неправильно. Представьте, что «сестринская» очередь точно такая же, но с указателем на другой тип для «события».

Должен ли я вместо этого использовать союз? такие как

typedef struct event_queue{
union{
  Event* event;
  VisualEvent* visual;
} data;
unsigned char* datatype; //array of same size as data for every individual member
int size;
int front;
int count;
int delay;
} event_queue;

Но как в таком случае выделить память для массива? Должен ли я держать их отдельно, и это плохая идея?


person Delirium_4    schedule 21.11.2011    source источник


Ответы (1)


Одно из решений — сделать базовый тип события union, возможно, помеченным:

enum EEventType { TypeOne, TypeTwo };

typedef struct EventTag_
{
  EEventType tag;
} EventTag;

typedef struct EventOne_
{
  EEventType tag;
  // real data for this event type;
} EventOne;

typedef struct EventTwo_
{
  EEventType tag;
  // real data for the sister event type;
} EventTwo;

typedef union Event_
{
  EventTag kind;
  EventOne event1;
  EventTwo event2;
} Event;

Теперь создайте массив из Events. Для каждого Event * p вы можете проверить e->kind.tag независимо от того, какой член объединения активен в данный момент (благодаря специальному правилу, касающемуся начальных последовательностей членов объединения структур).

person Kerrek SB    schedule 21.11.2011
comment
О, я серьезно не думал об этом. Я попробую это прямо сейчас! - person Delirium_4; 21.11.2011
comment
Извините, я думаю, что я немного ошибся в последнем союзе. Я думаю, что теперь все в порядке. В качестве альтернативы вы можете сделать Event struct { EEventType tag; union { EventOne e1; EventTwo e2; } }; - person Kerrek SB; 21.11.2011