I have an array of such structures:
typedef struct month {
char cName[20];
char cAbbr[20];
int iDays;
int iNumber;
} MONTH;
which is nested in another structure:
typedef struct input{
MONTH * pMonths;
DATE sDate;
CALCS sCalcs;
} INPUT;
I initialize this array of structs in stack like that:
MONTH * init_months(bool bLeap) {
MONTH months[NUM_MONTHS] = {
{ .cName = "January", .cAbbr = "Jan", .iDays = 31, .iNumber = 1 },
{ "February", "Feb", 28, 2 },
{ "March", "Mar", 31, 3 },
{ "April", "Apr", 30, 4 },
{ "May", "May", 31, 5 },
{ "June", "Jun", 30, 6 },
{ "July", "Jul", 31, 7 },
{ "August", "Aug", 31, 8 },
{ "September", "Sep", 30, 9 },
{ "October", "Oct", 31, 10 },
{ "November", "Nov", 30, 11 },
{ "December", "Dec", 31, 12 }
};
if(bLeap){
months[1].iDays ;
}
return months;
}
The question is, if i form a INPUT structure inside some function:
INPUT GetUserInput(void){
// init months
MONTH * pMonths;
pMonths = init_months(isLeap(sDate.iYear));
// some code here
...
INPUT sInput = { pMonths, sDate, sCalcs };
// return
return sInput;
}
then how to properly initialize array of MONTH and/or how to properly initialize INPUT so it would contain valid data when returned from GetUserInput() ?
CodePudding user response:
You have 3 options:
- Make it static (but all returned references will reference the same array).
static MONTH months[NUM_MONTHS] = {
- Use malloc and compound literal
MONTH *months = malloc(sizeof(*months) * NUM_MONTHS);
/* check if memory was allocated */
memcpy(months, (MONTH[]){
{ .cName = "January", .cAbbr = "Jan", .iDays = 31, .iNumber = 1 },
{ "February", "Feb", 28, 2 },
{ "March", "Mar", 31, 3 },
{ "April", "Apr", 30, 4 },
{ "May", "May", 31, 5 },
{ "June", "Jun", 30, 6 },
{ "July", "Jul", 31, 7 },
{ "August", "Aug", 31, 8 },
{ "September", "Sep", 30, 9 },
{ "October", "Oct", 31, 10 },
{ "November", "Nov", 30, 11 },
{ "December", "Dec", 31, 12 }}, sizeof(*months) * NUM_MONTHS);
- Wrap the table into another structure and return by value
typedef struct
{
MONTH months[NUM_MONTHS];
}YEAR;
YEAR init_months(bool bLeap) {
YEAR year = {{
{ .cName = "January", .cAbbr = "Jan", .iDays = 31, .iNumber = 1 },
{ "February", "Feb", 28, 2 },
{ "March", "Mar", 31, 3 },
{ "April", "Apr", 30, 4 },
{ "May", "May", 31, 5 },
{ "June", "Jun", 30, 6 },
{ "July", "Jul", 31, 7 },
{ "August", "Aug", 31, 8 },
{ "September", "Sep", 30, 9 },
{ "October", "Oct", 31, 10 },
{ "November", "Nov", 30, 11 },
{ "December", "Dec", 31, 12 }}};
if(bLeap){
year.months[1].iDays ;
}
return year;
}