【问题标题】:How to properly initialize array of structures inside another structure and return it from function?如何正确初始化另一个结构内的结构数组并从函数中返回它?
【发布时间】:2022-01-25 10:09:55
【问题描述】:

我有一个这样的结构数组:

typedef struct month {
    char cName[20];
    char cAbbr[20];
    int iDays;
    int iNumber;
} MONTH;

嵌套在另一个结构中:

typedef struct input{
    MONTH * pMonths;
    DATE sDate;
    CALCS sCalcs;
} INPUT;

我像这样在堆栈中初始化这个结构数组:

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;
}

问题是,如果我在某个函数中形成 INPUT 结构:

INPUT GetUserInput(void){

    // init months
    MONTH * pMonths;
    pMonths = init_months(isLeap(sDate.iYear));

    // some code here
    ...
    INPUT sInput = { pMonths, sDate, sCalcs };

    // return
    return sInput;
}

然后如何正确初始化 MONTH 数组和/或如何正确初始化 INPUT 使其在从 GetUserInput() 返回时包含有效数据强>?

【问题讨论】:

  • return months; 尝试返回init_months() 的本地数组。当您声明 MONTH months[NUM_MONTHS] = {...} 时,它会以 自动存储持续时间 创建,并在函数返回时结束。 (内存驻留在函数堆栈上,返回时释放以供重用)您可以从months分配12个struct monthmemcpy()到分配的块,并返回指向已分配内存块的指针分配的存储持续时间,直到在内存块上调用free()
  • 另一种选择是将MONTH * pMonths;更改为MONTH Months[12];,然后您可以将MONTH * init_months(bool bLeap)更改为INPUT init_months(bool bLeap)并在int_months()内的结构中填充数组并返回结构(一个函数总是可以返回自己的类型)
  • 两个选项有什么区别?
  • 首先在MONTH * init_months(bool bLeap)memcpy() monthspmonths 中动态分配MONTHS *pmonths = malloc (12 * sizeof *pmonths); 并返回pmonths。第二步,将指针pmonths 更改为struct input 中的数组,并使函数返回类型INPUT。您可以在结构中填充数组,然后返回结构。
  • 这里是 An Example of the 2nd Option(链接有效 30 天)注意 DATECALCS 类型已更改为 int 出于示例的目的(您没有提供任何声明)

标签: c c99


【解决方案1】:

您有 3 个选项:

  1. 将其设为静态(但所有返回的引用都将引用同一个数组)。
    static MONTH months[NUM_MONTHS] = {
  1. 使用 malloc 和复合字面量
    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. 将表格包装成另一个结构并按值返回
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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多