Home > database >  How to properly initialize array of structures inside another structure and return it from function?
How to properly initialize array of structures inside another structure and return it from function?

Time:12-25

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:

  1. Make it static (but all returned references will reference the same array).
    static MONTH months[NUM_MONTHS] = {
  1. 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);
  1. 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;
}
  •  Tags:  
  • c c99
  • Related