【问题标题】:What is the use of malloc? Why not just... not use it?malloc有什么用?为什么不只是...不使用它?
【发布时间】:2014-02-27 23:40:04
【问题描述】:

我正在关注 this tutorial 学习 C,它说如下:

假设我们要动态分配人员结构。人是这样定义的:

typedef struct {
    char * name;
    char age;
} person;

要在 myperson 参数中分配一个新人,我们使用以下语法:

person * myperson = malloc(sizeof(person));

他们为什么这样做? malloc 带来什么好处?

以下代码可以编译并且看起来工作正常:

typedef struct {
    char * name;
    char age;
} person;

person p;
p.name = "Henry";
p.age = 9;

printf("%s is %d", p.name, p.age);

我很困惑为什么要使用malloc

【问题讨论】:

  • 好的,创建一个人员数组。从标准输入(或从 argv)获取人数。
  • @user3125367:您实际上可以在没有 malloc() 的情况下使用 VLA...例如 int numperson = strtol(argv[1], 0, 0); struct person persons[numperson];
  • malloc() 在您想要创建一个比创建函数调用寿命更长且不是全局的数据结构时很有用。
  • 好的,创建一个返回它的函数。
  • ..然后创建一个返回 100,000 个数组的数组,然后将其排队到另一个线程。

标签: c memory memory-management malloc


【解决方案1】:

malloc至少用于3个场景:

  1. 当构建一个数组并且创建的元素数量是未知的或变量时(尽管 C99 允许为数组定义运行时大小)。作为一种特殊情况,可变长度 char 字符串。
  2. 当请求非常大的内存块时,堆栈不适合作为全局变量的替代方案。
  3. 每当需要动态管理内存时,即显式且急切地分配和释放内存,以减少占用空间。

但这绝不是编程所必需的。

当然,如果没有它,很多事情会更难实现,但它并不是绝对必要的。事实上,一些特殊应用的编码风格(如航空电子设备的 DO-178B)实际上禁止使用它。

【讨论】:

    【解决方案2】:

    Malloc 为您提供了动态分配内存的灵活性,并在您需要时使用它并在您不需要时释放它。在上述情况下,为人 p 分配的内存将一直保留到堆栈的末尾。您可能在当前示例中找不到它的用途。但是在很多情况下动态分配内存是有意义的。

    【讨论】:

    • 你能举一个这种情况的例子吗?
    • 你想要分配和释放内存的例子吗?抱歉,我没有完全明白你的问题。
    【解决方案3】:

    提供的示例并没有真正展示“malloc”的全部功能,就这么简单。

    想象一个你不知道最大金额的应用程序,比如说银行账户......(对于这个例子,钱只是整数)

    现在,你是一名程序员,所以余额大概可以存储在一个 16 位数字中,分两个账户:

    unsigned int * array = malloc(2 * sizeof(unsigned int)); //This allows the array 
                                                             //to have two indexes.
    

    现在,假设我们现在需要添加另一个帐户...

    如果我们不是很聪明并使用了 malloc,我们会被塞满的。

    但是,我们现在可以说:

    realloc(3 * sizeof(unsigned int));
    

    并添加更多银行账户 :)

    【讨论】:

    • realloc 调用在幕后发生了什么?它是如何连接到阵列的?然后我将如何向数组中添加更多内容?
    【解决方案4】:

    另一种看法是why use a pointer to my struct rather than just the struct,因为当您想到malloc() 时,您会想到指针。使用指针以及 malloc() 的一个好处是调用函数时的开销。当您的数据结构变得更加复杂时,当您将它们作为参数传递给函数时,它们的开销将会增加。解决此问题的一种方法是仅将指针传递给您的结构,然后在函数中取消引用它。

    void printfStruct(struct myStruct) 
    {
        printf("%s", myStruct.name);
        // no pointer passed, overhead created on larger data structures
    }
    
    void printfStruct(struct *myStruct)
    {
        printf("%s", myStruct->name);
        // pointer passed, then dereferenced. Decreased overhead on larger data structures.
    }
    

    【讨论】:

      【解决方案5】:

      Malloc 用于 在运行时分配内存。如果您不确定确切的人数,则可以在运行时确定并为其分配合适的内存。

      malloc 连续分配内存……也就是说,你可以做指针运算

      当你想释放内存时,你可以给 free() ,这会释放整个内存块,不管大小太大或太小。

      还要注意 malloc 没有任何默认值,因此默认情况下它包含垃圾值...如果要将默认值设置为零,请使用 calloc 而不是 malloc。

      如果没有可用的连续空间,则 malloc 返回 null 值,因此在这种情况下无法分配内存

      【讨论】:

        猜你喜欢
        • 2013-01-11
        • 2012-09-08
        • 2017-03-16
        • 2019-09-10
        • 2013-06-16
        • 1970-01-01
        • 2017-10-08
        • 2010-09-07
        相关资源
        最近更新 更多