Reputation: 573
I'm having trouble finding the answer to this problem; I've found similar examples of this online but none that address my problem.
I have a struct
for the data for a company, Company, and a second struct
for collections of companies, Consortium. The second struct
will contain variable length arrays of the first struct
, the company data struct
. The number of elements of the variable length arrays will depend on the number of companies in a consortium.
I want to dynamically allocate whatever is required but I'm getting a bit lost. These are the structs:
typedef struct {
char code[];
double sharePrice;
int numShares;
double totalVal;
double totalDebts;
} Company;
typedef struct {
int numCore;
int numAssoc;
Company core[];
Company assoc[];
} Consortium;
There will be a number of core companies, and this number will be the size of the core array in the Consortium struct
. Same goes for associate companies.
I came up with this expression but I'm not sure what I'm missing:
Consortium *consort=((Consortium*)malloc((numCore+numAssoc)*(sizeof(Consortium));
Upvotes: 0
Views: 3216
Reputation: 17723
You might consider that you make the Consortium struct a bit simpler. Since you have the counts for each type, core and assoc, you can have just a single array, the first part of which is for core and the second part of which is for assoc.
So your struct would look something like the following source (which has not been compiled and is just jotted down rather than tested so caveat 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;
Then you would create your actual data structure by something like:
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;
}
After this you could fill it in by some functions which indicate success or not:
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;
}
And then you would access them with another set of helper functions.
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;
}
Upvotes: 0
Reputation: 755114
You'll need to use pointers and allocate the arrays separately:
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!
It would be simpler and possibly better to modify the Company
type to:
typedef struct
{
char code[32];
double sharePrice;
int numShares;
double totalVal;
double totalDebts;
} Company;
That saves the loops allocating the code elements.
Upvotes: 3