【问题标题】:Difference between two malloc definition of a struct结构的两个malloc定义之间的区别
【发布时间】:2013-03-12 10:05:48
【问题描述】:

我想知道这之间是否有真正的区别:

c = (struct_t *) malloc(sizeof(struct_t));

还有这个

c = malloc(sizeof(struct_t *));

除了避免强制转换之外,编译器在第二种形式方面是否利用了第一种形式?或者这两种方式完全一样,只是一个“审美”的问题?

【问题讨论】:

  • hmmm...我有一个typedef struct struct_t { .... } struct_t;,我声明struct_t * c;
  • 啊,好吧。你是对的。第二种形式可能是:c = malloc(sizeof(*c));。不是吗?
  • @Kyrol 使用c = malloc(sizeof(struct_t)); 并忘记其他情况,它们可能对您尝试做的事情没有意义。
  • 所以我只能避免演员阵容。对?但是您确定如果我将 c 声明为指针,那么您的形式是正确的吗?我想知道为什么是正确的。 :)

标签: c compiler-construction casting malloc


【解决方案1】:

第一个分配sizeof(struct_t)字节,第二个分配sizeof(struct_t*)字节。

除此之外,malloc 所做的事情没有任何区别,无论您是否投射结果。转换结果使得代码可以被 C++ 编译器接受,但它可以隐藏不包含 stdlib.h 的错误,因此人们普遍倾向于不将结果转换为 C。

【讨论】:

  • 那么,出于这个原因,我使用第一个还是第二个更好?
  • 嗯,你必须使用正确的尺寸。然后,如果你有这个,我更喜欢没有强制转换的版本,因为强制转换是不必要的(如果你不严格编译为禁止隐式声明的标准,可以隐藏错误)。 C++ 人通常更喜欢有演员表的那个。
  • C++ 人应该使用new,使用 C 编译器编译 C 代码,并将其链接到他们的 C++ 项目...
  • ...而且 malloc 并不是使用 C 编译器而不是 C++ 编译器编译 C 代码的唯一原因。
  • @modifiablelvalue C++ 人的新观点是,如果我的印象没有误导我,他们甚至不应该使用new。我强烈同意 C 代码应该用 C 编译器编译。
【解决方案2】:

两者完全不同。第一个分配结构的一个实例,而第二个分配一个指向结构的指针

一般来说,它们甚至不会分配相同数量的字节。

【讨论】:

    【解决方案3】:

    不,它们不一样。后者为指向结构的指针分配 4 或 8 个字节的空间,第一个为它自己的结构分配足够的空间。

    当 sizeof(struct_t) 足够小时,当 malloc 分配的实际比请求的多时,用户可能看不到差异。

    【讨论】:

    • 好的,我明白了。我一直使用第一种形式,但最近我也看到了第二种形式,我想了解是否有任何重大差异。谢谢。
    • 很少需要为 single 指针分配空间。更像是需要重新设计界面。
    【解决方案4】:

    两种形式不同。它们都分配内存,但数量不同。 一般规则如下: 分配类型 T 时,malloc 的结果应强制转换为 T*。

    void sample1()
    {
        struct pollfd *pfd = (struct pollfd*)malloc(sizeof(struct pollfd));
        // pfd is points to a memory with a size of struct pollfd
        ...
        free(pfd);
    }
    
    void sample2()
    {
        struct pollfd *pfd = (struct pollfd*)malloc(sizeof(*pfd));
        // same as above, but uses variable type instead
        free(pfd);
    }
    

    如果你在 malloc 参数中指定了错误的类型,通常会导致缓冲区溢出问题:

    void sample3()
    {
        struct x *px= (struct x*)malloc(sizeof(struct x*));
        x->field = 5; //<< error, as allocated only 4 or 8 bytes depending on pointer size
    }
    

    【讨论】:

      【解决方案5】:

      两者都不一样。

      通常 malloc 返回 (void*)。所以你想将 void* 类型转换为 (struct_t*)。

      【讨论】:

      • 不,你绝不能在 c 中对 malloc 进行类型转换,see this
      • 但我曾经对我的所有程序进行类型转换。它可以正常工作,没有任何错误或崩溃,为什么?
      • 这是answer,你的问题,如果你有时间/耐心,去看看那里,但我没有时间/耐心向你解释答案,这是在我发送的链接中清楚地解释了。
      • 感谢 Barath Bushan 先生。我清除了您发送的链接。
      • 没问题,只是更正你关于类型转换 malloc 的答案
      猜你喜欢
      • 2021-04-12
      • 1970-01-01
      • 1970-01-01
      • 2015-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-13
      相关资源
      最近更新 更多