Неправильный массив структур внутри структуры (C)

У меня проблемы с поиском ответа на эту проблему; Я нашел подобные примеры в Интернете, но ни один из них не касается моей проблемы.

у меня есть struct для данных для компании, компании и второй struct для коллекций компаний, Консорциум. Второй struct будет содержать переменные длины массивов первого structданные компании struct, Количество элементов массивов переменной длины будет зависеть от количества компаний в консорциуме.

Я хочу динамически распределять все, что требуется, но я немного теряюсь. Это структуры:

typedef struct {
    char  code[];
    double sharePrice;
    int numShares;
    double totalVal;
    double totalDebts;
} Company;

typedef struct {
    int numCore;
    int numAssoc;
    Company core[];
    Company assoc[];
} Consortium;

Будет несколько основных компаний, и это число будет размером основного массива в Консорциуме. struct, То же самое касается ассоциированных компаний.

Я придумал это выражение, но я не уверен, что мне не хватает:

Consortium *consort=((Consortium*)malloc((numCore+numAssoc)*(sizeof(Consortium));

2 ответа

Решение

Вам нужно будет использовать указатели и распределять массивы отдельно:

typedef struct
{
    char  *code;
    double sharePrice;
    int numShares;
    double totalVal;
    double totalDebts;
} Company;

typedef struct
{
    int numCore;
    int numAssoc;
    Company *core;
    Company *assoc;
} Consortium;

Consortium *c = malloc(sizeof(*c));    // Error check
c->numCore = 4;
c->core = malloc(sizeof(*c->core) * c->numCore);    // Error check
c->numAssoc = 3;
c->assoc = malloc(sizeof(*c->assoc) * c->numAssoc);    // Error check

for (int i = 0; i < c->numCore; i++)
    c->core[i].code = malloc(32);    // Error check

for (int i = 0; i < c->numAssoc; i++)
    c->assoc[i].code = malloc(32);    // Error check

// Worry about other data member initializations!

Было бы проще и, возможно, лучше изменить Company введите:

typedef struct
{
    char   code[32];
    double sharePrice;
    int    numShares;
    double totalVal;
    double totalDebts;
} Company;

Это сохраняет циклы, выделяющие элементы кода.

Вы можете подумать, что вы делаете структуру Консорциума немного проще. Поскольку у вас есть счетчики для каждого типа, ядра и ассоциации, вы можете иметь только один массив, первая часть которого предназначена для ядра, а вторая часть - для ассоциаций.

Таким образом, ваша структура будет выглядеть примерно следующим образом (который не был скомпилирован и просто записан, а не протестирован, поэтому будьте внимательны с emptor):

typedef struct {
    int numCore;    // number of core companies, first part of m_companies
    int numAssoc;   // number of assoc companies, second part of m_companies
    Company m_companies[1];
} Consortium;

Тогда вы бы создали свою фактическую структуру данных, например:

Consortium *makeConsortium (int numCore, int numAssoc) {
  Consortium *pConsortium = malloc (sizeof(Consortium) + sizeof(Company) * (numCore, numAssoc));
  if (pConsortium) {
      pConsortium->numCore = numCore;
      pConsortium->numAssoc = numAssoc;
  }
  return pConsortium;
}

После этого вы можете заполнить его некоторыми функциями, которые указывают на успех или нет:

int addCompanyCore (Consortium *pConsortium, int index, Company *pCompany) {
  int iRetStatus = 0;
  if (pConsortium && index < pConsortium->numCore) {
    pConsortium->m_companies[index] = *pCompany;
    iRetStatus = 1;
  }
  return iRetStatus;
}
int addCompanyAssoc (Consortium *pConsortium, int index, Company *pCompany) {
  int iRetStatus = 0;
  if (pConsortium && index < pConsortium->numAssoc) {
    index += pConsortium->numCore;
    pConsortium->m_companies[index] = *pCompany;
    iRetStatus = 1;
  }
  return iRetStatus;
}

И тогда вы получите к ним доступ с помощью другого набора вспомогательных функций.

Company  *getCompanyCore (Consortium *pConsortium, int index) {
  Company *pCompany = 0;
  if (pConsortium && index < pConsortium->numCore) {
    pCompany = pConsortium->m_companies + index;
  }
  return pCompany;
}
Company * getCompanyAssoc (Consortium *pConsortium, int index) {
  Company *pCompany = 0;
  if (pConsortium && index < pConsortium->numAssoc) {
    index += pConsortium->numCore;
    pCompany = pConsortium->m_companies + index;
  }
  return pCompany;
}
Другие вопросы по тегам