【问题标题】:Allocating an Array of Structs without Malloc?在没有 Malloc 的情况下分配结构数组?
【发布时间】:2013-09-19 17:58:12
【问题描述】:

我有一个以这种方式定义的结构。

typedef struct COUNTRY {
    char Code[3];
    char Country[30];
    int Population;
    float Expectancy;
    struct Country *Pointer;
} COUNTRY;

我见过这样分配的结构数组:

COUNTRY *countries = calloc(128, sizeof(COUNTRY));

或者可能是这样的:

COUNTRY *countries = malloc(128 * sizeof(COUNTRY));

但这有什么作用:

COUNTRY countries[128] = {};

因为我仍然能够在所有情况下写入每个条目的字段。第三种选择只是不好的形式吗?对我来说这似乎更好,因为您可以将该行与 main() 的其余变量声明外部放在一起。否则,您只能在 main() 或其他函数中使用 calloc() 或 malloc()。

我做错了吗?

【问题讨论】:

    标签: c arrays struct


    【解决方案1】:

    这个:

    COUNTRY countries[128];
    

    只定义一个类型为“128个COUNTRY元素的数组”的对象。

    = {} 是一个初始化器——但空初始化器在 C 中是非法的(我认为 gcc 支持它们作为扩展)。便携式替代方案是:

    COUNTRY countries[128] = { 0 };
    

    将所有元素的所有成员初始化为零(0 用于整数,\0' 用于字符,0.0 用于浮点,NULL 用于指针,递归用于子元素)。但是由于您指定了数组中的元素数量(如128),因此初始化程序对数组对象的分配方式没有影响。

    如果声明发生在函数定义中,则数组对象具有自动存储持续时间,这意味着当执行到达封闭块的末尾时它不再存在。此类对象通常分配在“堆栈”上。

    如果它出现在任何函数定义之外(在文件范围如果它有关键字static,那么它有静态存储持续时间 em>,这意味着它在程序的整个执行过程中继续存在。

    使用malloccalloc 分配的对象具有已分配的存储持续时间,这意味着它们将继续存在,直到通过调用free() 显式释放它们。此类对象通常分配在“堆”上。 (我忽略了realloc(),这使描述有点复杂。)

    【讨论】:

    • 比我的答案更好 - +1。
    【解决方案2】:

    前两个语句将在堆上分配结构数组,而最后一个语句将在堆栈上初始化结构数组。

    这不是一个糟糕的形式,这只是您希望将数据存储在哪里的问题 - 在堆栈上(当您的变量超出范围时自动释放,堆栈的大小通常比堆小得多,所以您如果将大数据结构放在那里可能会溢出),或者堆上(数据的生命周期与范围无关,您需要手动释放内存)。

    这对我来说似乎更好,因为您可以将该行与 main() 之外的其余变量声明放在一起。

    如果您需要在程序的生命周期内静态分配对象,请使用这种方法,它没有任何问题。请注意,在这种特殊情况下,变量不存储在堆栈中,而是存储在程序的 .data 段中(有关详细信息,请查看此问题:How are global variables stored?)。

    【讨论】:

    • 除了生命周期的差异之外,在许多系统上堆栈大小远小于堆大小,因此许多人倾向于避免在堆栈上分配大数组。
    【解决方案3】:

    最后一种形式是“堆栈分配”或“静态分配”。和 calloc 一样,所有的字段都会被清零。

    在函数内部,它是“堆栈分配的”,当函数返回时,该内存将消失。

    在任何函数之外,在文件范围内,它是静态分配的,并且在 main() 启动之前分配了一块全局内存。

    【讨论】:

      【解决方案4】:

      malloc/calloc 在编译时不知道需要多少时使用。例如,在链表中,您需要动态分配/取消分配节点。使用数组时,您在编译时就知道需要多少个。

      不同的是从哪里获取内存。如果在函数中声明数组,则内存将从stack 中获取。在 malloc/calloc 的情况下,内存是在heap 中预留的。

      【讨论】:

        【解决方案5】:

        = {};

        是 GNU C 扩展,与以下相同:

        = {0};

        【讨论】:

          猜你喜欢
          • 2015-07-20
          • 2016-04-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-05-29
          • 1970-01-01
          • 2017-05-30
          • 1970-01-01
          相关资源
          最近更新 更多