【问题标题】:What is the intention/benefit of malloc returning type void *?malloc 返回类型 void * 的意图/好处是什么?
【发布时间】:2013-06-20 03:17:16
【问题描述】:

比 CI 了解更多的 C++ 想知道是否有人可以解释为什么 malloc() 总是返回类型为 void 的指针,而不是 malloc 已通过某种机制实现,该机制允许它返回用户传入的类型的指针?不断地显式地将返回的 void 指针转换为您想要的类型似乎有点“hacky”。​​

【问题讨论】:

  • 用户传入的类型?你是说size_t
  • C 中没有泛型,而且 malloc 不必是宏。因此,您别无选择,只能将 malloc 返回类型定义为 void* 。
  • 请注意,您不必(根据包括我在内的一些人的说法,不应该cast the return value of malloc。在 C 中,存在从 void * 到任何指针类型的隐式转换。
  • @StilesCrisis,什么是 C++ 模式? C 和 C++ 是不同的语言,用一种语言编写的代码通常对于另一种来说不是很好的代码。特别是,C++ 代码不应该直接使用malloc,而是直接使用new。所以在 C++ 中并没有真正的需要。
  • @JensGustedt 将 C 编译为 C++ 有时确实会发生。使用某些工具集,将所有内容编译为 C++ 比选择性地将某些文件编译为 C 更容易。有时您甚至没有 C 编译器。 #ifdef __cplusplus extern "C" { #endif 出现在全世界的 C 文件中是有原因的。

标签: c linux pointers memory-management malloc


【解决方案1】:

好吧,在 C 语言中,您不必进行强制转换,因此您的观点没有实际意义。也就是说,这两个语句是 100% 等价的:

 char *x = malloc(100);
 char *y = (char *)malloc(100);

void * 之间的转换是隐含在C 中的。因此,为了解决您的问题,非常原因 malloc 返回void * 是为了让您不要 必须投射。

除此之外,在 C 中没有办法传递类型信息,所以可以这样做:

 char *x = malloc(100, char);

不可能。

如果您使用 C++,则强制转换是必要的,但无论如何您都不应该使用 malloc - 这就是 new 的用途,它确实可以正确处理类型信息。

【讨论】:

  • 可以使用宏传递类型:#define ALLOC(t, n) (((t) *)malloc(sizeof(t) * (n)))。只是没有必要。
  • @larsmans - 是的,但我认为 OP 在问为什么 malloc 本身没有这样的界面。
  • 我也这么认为,为您的回答 +1。我只是在回复“不可能”的评论。
【解决方案2】:

从 C 标准 ISO/IEC 9899 2011 的第 6.2.2.3 节开始,它一点也不 hacky:

指向 void 的指针可以转换为指向任何对象类型的指针或从指向任何对象类型的指针转​​换。指向任何对象类型的指针都可以转换为指向 void 的指针并再次返回;结果应与原始指针比较。

因此,指向void* 的指针是指向您想要的任何类型的有效指针,无需显式强制转换。

除此之外,您不能动态地将类型传递给函数以使其返回正确的类型,您可以只传递大小本身(因此 malloc 将能够分配 size_t count * size_t size 但不返回在任何情况下都正确输入)。

【讨论】:

    【解决方案3】:

    C 根本没有“传递类型”的机制。此外,在 C 中,从 void* 到任何其他类型的指针的转换是自动的(不需要强制转换),因此 malloc 在 C 中很自然地工作。只有在 C++ 中 malloc 需要强制转换才能工作。

    【讨论】:

      【解决方案4】:

      有两个原因,第一,malloc 不知道你为什么需要内存。所以它只返回要求返回的字节数。其次,您不能轻易取消引用 void * ,因此它可以帮助您避免意外。

      int *p;
      p = (int *)malloc(sizeof(int)*10);
      

      【讨论】:

        猜你喜欢
        • 2017-12-03
        • 1970-01-01
        • 2020-07-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-05
        相关资源
        最近更新 更多