【问题标题】:What's the difference between initializing this structure with these strategies?用这些策略初始化这个结构有什么区别?
【发布时间】:2011-02-26 11:01:38
【问题描述】:
// the malloc style, which returns a pointer:
struct Cat *newCat = malloc(sizeof(struct Cat));

// no malloc...but isn't it actually the same thing? uses memory as well, or not?
struct Cat cat = {520.0f, 680.0f, NULL};

基本上,我可以通过这两种方式获得一个初始化的结构。我的猜测是:这是一回事,但是当我使用 malloc 时,我还必须 free() 。在第二种情况下我不必考虑内存,因为我不调用malloc。也许吧。

什么时候应该使用 malloc 样式,什么时候使用另一个?

【问题讨论】:

    标签: c


    【解决方案1】:

    首先,第一个变体没有初始化任何结构。它只是分配一块足以容纳struct Cat 类型的对象的原始内存块。内存保持未初始化(包含垃圾)。第二个变体确实将结构中的每个字段初始化为特定值。

    其次,第一个变体创建了一个无名 [和未初始化] struct Cat 对象,具有已分配 存储持续时间。该对象将一直存在,直到您使用 free 显式取消分配它(或直到程序结束)。第二个变体创建一个具有自动存储持续时间的命名对象cat——它将在其声明性区域的末尾(在包含块的末尾)自动释放。

    第三,在实践中,这两种变体在不同类型的内存中创建对象。第一个变体在堆中创建对象,而第二个变体通常在堆栈上创建它。

    至于何时使用一个或另一个,这里有很多关于这个问题的答案。 This thread 有一些答案和大量链接。

    【讨论】:

      【解决方案2】:

      不同之处(已经说过的其他几点)是在第一种情况(malloc)中您根本没有初始化结构;你只是得到记忆来保存它。在第二种情况下,你有内存和初始化。

      【讨论】:

      • +1 是我在 c 中遇到的最常见错误之一。
      【解决方案3】:

      除了其他非常有用的答案之外,还有一个关键区别。

      malloc() 方法使结构成员保持未初始化状态。您必须在单独的步骤中初始化它们。

      【讨论】:

        【解决方案4】:

        不是同一个内存,前者分配在堆上,后者分配在栈上。

        堆可以让你手动控制创建和删除,有利有弊:你可以将指针传递给其他人,但你也必须删除它。

        只要有可能,就首选第二个。

        【讨论】:

        • 我不会说“只要有第二个可能,它就是首选”。例如,当 Cat 是一个沉重的对象时,可能最好传递指向 Cat 的指针而不是对象本身。
        • 但是您仍然可以将指针传递给堆栈上的变量。虽然我同意。
        • 实际上,如果第二次分配是全局或静态的,那么内存可能在数据或文本段中,而不是在堆栈或堆中。
        • @torak,真的。但是我们不要混淆初学者:)
        • @torak:OP 显然是在谈论两者可以互换的情况,这让我们只能了解当地情况。
        【解决方案5】:

        malloc 函数只应在您需要结构超过当前函数的生命周期时使用。 malloc 函数将从堆中分配内存,使其能够长期存在。如果您需要在函数退出后存储项目(例如在共享列表中),这很有用。

        它还引入了额外的开销,包括...

        • 强制对代码进行更多错误检查
        • 结构的分配和初始化分离
        • 跟踪内存的过程中的开销

        另一方面,第二种语法在堆栈上分配内存。这是有益的,因为这里的记忆是自动的,你不必考虑它。可以说,当函数退出时,内存被释放。此外,它允许使用单个语句进行分配和初始化。

        这个规则的一个例外是结构足够大,可能导致堆栈溢出。堆栈是一种有限的资源,大的结构可能会导致它被耗尽。一般来说,堆有更多的空间,可以很容易地容纳这些更大的结构。

        【讨论】:

        • ... 或者结构太大会溢出堆栈。
        • 大脑运行时错误:在方法内部:为什么我可以将 CGRect 分配给 CGRect iVar 而不会弄乱 malloc?即使方法完成,CGRect 结构数据仍然存在。没有malloc。还是您的理论仅适用于 C 函数?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-14
        • 1970-01-01
        • 2017-03-23
        相关资源
        最近更新 更多