【问题标题】:In C are malloc(256) and malloc(sizeof(char)*256) equivalent?在 C 中 malloc(256) 和 malloc(sizeof(char)*256) 是否等效?
【发布时间】:2011-03-10 21:00:53
【问题描述】:

我看到人们经常写C代码比如:

char *ptr = malloc(sizeof(char)*256);

真的有必要吗?该标准根据定义说sizeof(char)==1,所以只是写没有意义:

char *ptr = malloc(256);

【问题讨论】:

  • 还值得注意的是 sizeof() 运算符是在编译时评估的,因此使用 sizeof() 不会影响运行时性能。 (除了在运行时指定数组长度的情况,但这不是您使用的示例。)
  • calloc “稍微慢一些,因为它必须用零清除分配的内存。

标签: c pointers malloc sizeof


【解决方案1】:

是的,C 始终将sizeof(char) 定义为 1(C++ 也是如此)。

不过,作为一般规则,我建议如下:

char *ptr = malloc(256 * sizeof(*ptr));

这样,当你的老板说:“哦,顺便说一句,我们刚接到中国的订单,所以我们需要尽快处理所有三个中文字母”,你可以将其更改为:

wchar_t *ptr // ...

其余的可以保持不变。考虑到你将有大约 1000 万头在尝试合理地处理 i18n 时感到头疼,因此即使消除一些也是值得的。当然,这假设通常情况下,您的 chars 确实打算保存字符 - 如果它只是某种原始缓冲区,并且您真的想要 256 字节的存储空间,无论有多少(少数)可能的字符,您应该坚持使用malloc(256) 并完成它。

【讨论】:

  • @rascher:那里没有sizeof(*type)ptr 不是类型。它是一个指针变量。
  • @rascher:澄清一下,您可以使用sizeof(type)sizeof(expression)。在后一种情况下,编译器推断出表达式的类型,但表达式本身是计算的,因此它不需要包含有效值(例如,似乎取消引用空指针或未初始化指针的代码仍然是很好)。
  • @Jerry Coffin:实际上是sizeof(type)sizeof expression,这意味着没有必要将() 中的表达式包围起来,除非需要覆盖优先级。
  • 更改字符串类型以支持国际化确实是倒退。任何现代事物都使用 UTF-8。
  • 在 C 中,wchar_t 很痛苦,因为它依赖于平台。更重要的是,因为大多数库(Windows API 除外)仍然需要char* 字符串。
【解决方案2】:

这个问题甚至不应该存在。您应该采用更优雅的方式将您的malloc 写为

ptr = malloc(N * sizeof *ptr)

即尽可能避免提及类型名称。类型名称用于声明,而不用于声明。

这样您的mallocs 将始终与类型无关并且看起来一致。乘以 1 是多余的这一事实将不那么明显(因为有些人觉得乘以 sizeof(char) 很烦人)。

【讨论】:

    【解决方案3】:

    它们是等价的,但保持一致是件好事。它也使它更明确,所以很明显你的意思。如果类型发生变化,更容易找出需要更新的代码。

    【讨论】:

      【解决方案4】:

      这可能是真的,但仅适用于 char 的特定情况。

      我个人认为使用malloc(sizeof(char) * 256) 表单是一种很好的形式,因为有人更改类型,或者出于类似目的而使用不同类型复制代码可能会错过这种情况的微妙之处。

      【讨论】:

      • sizeof(char) * 256 如果有人更改类型,对您没有帮助;你的意思是sizeof *ptr * 256
      • @Charles,同意,他们仍然需要更改声明中的类型,但至少那样它会是明确的,而不仅仅是一个数字。
      【解决方案5】:

      虽然写sizeof(char) 在技术上没有任何问题,但这样做表明作者不熟悉C 以及sizeof(char) 被定义为1 的事实。在我从事的一些项目中,我们实际上是grep for sizeof(char) 的实例表明代码可能质量低下。

      另一方面,ptr = malloc(count * sizeof(*ptr)); 是一个非常有用的文档和避免错误的习惯用法,即使sizeof(*ptr) 为 1 也有意义。但是,它需要在前面加上if (count > SIZE_MAX/sizeof(*ptr)) { /* handle overflow */ },否则你有一个严重的错误.这在分配 wchar_t 数组或与输入字符串长度相同的复杂结构时尤其重要,例如将 UTF-8 字符串转换为 wchar_t 字符串或构建 DFA 以匹配字符串时。

      【讨论】:

      • 值得注意的是,即使在 char 大于 8 位的系统上(我使用过 16 位的系统), sizeof(char) 仍然是 1; sizeof(int) 在这种情况下也是一个。我什至听说过 sizeof(long) 也是一个系统,因为“char”包含 64 位。
      【解决方案6】:

      是的,它们在技术上是等效的。这只是风格问题 - 每次分配都使用 sizeof 可以让您在真正需要它时不太可能错过它。

      【讨论】:

        猜你喜欢
        • 2010-09-29
        • 1970-01-01
        • 1970-01-01
        • 2013-02-19
        • 1970-01-01
        • 2014-08-13
        • 1970-01-01
        • 1970-01-01
        • 2022-06-14
        相关资源
        最近更新 更多