【问题标题】:is the order of parameters to calloc() important? [duplicate]calloc() 的参数顺序重要吗? [复制]
【发布时间】:2018-02-15 19:52:26
【问题描述】:

calloc() 处理 count 和 size 参数的方式有区别吗?例如:

// calloc() parms are "count", then "size"
ptr1 = calloc( 1, 20 );
ptr2 = calloc( 20, 1 );

显而易见的假设是,它在内部将两者相乘以获得总字节数,并且实际上并不关心哪个是计数,哪个是大小。但这是真的吗?

导致它的两个参数之间是否存在细微差别,因此我们应该小心传入哪个作为计数与大小?

(是的,我知道 calloc 可以通过使用 2 个参数来检测溢出,而 malloc() 不能,但这并不能回答我的问题。)

【问题讨论】:

  • 如果你颠倒了数字,你就会颠倒意思,如果你这样做,你就会看起来你不知道自己在做什么。
  • 将参数一分为二为分配器提供了更多可能在其分配方案中使用的信息。它可能不会使用它,但万一它使用,你就会对它撒谎。如果你对它撒谎,如果它表现不佳,是谁的错?
  • 您的问题的答案是,正如下面的答案(以及重复问题的答案)所指出的那样。但是,如果您想了解为什么会这样,请记住calloc 将尝试分配适当对齐的连续内存。连续性是允许参数交换的东西,适当的对齐确保您可以正确访问第一个(以及随后的)元素。
  • @user934063 你是想告诉我,如果我 calloc(3, 4) 与 calloc(4, 3) 并将其用作 12 个单字节的数组,则有些字节可能无效,由于对齐问题而无法获得或非零?我很难相信!
  • @Stéphane 如果这就是我所说的,我也很难相信这一点。不,这不是我想说的。我想说的是,如果不能保证连续性,那么calloc(2, 4) 原则上(阅读:思想实验)可以将这两个 4 字节元素存储在不同的位置,而不是“彼此相邻”。这与calloc(4, 2) 不同。因此要点:contiguity 是使交换性(即交换参数)成为可能的原因。要回答您关于对齐的问题,请参阅下一条评论...

标签: c calloc


【解决方案1】:

来自标准7.22.3.2

 void *calloc(size_t nmemb, size_t size);

说明

2) calloc 函数为nmemb 对象数组分配空间,每个对象的大小为size。该空间被初始化为所有位为零。

你可以看到它是如何使用它的。所以不,没关系,但不要这样做。对于将维护您的代码的未来程序员来说,语义有时会更好。

同样来自7.22.3p1

连续调用aligned_alloc、calloc、malloc 和realloc 函数分配的存储顺序和连续性未指定。 如果分配成功,则返回的指针经过适当对齐,以便可以将其分配给指向具有基本对齐要求的任何类型对象的指针,然后用于访问分配空间中的此类对象或此类对象的数组。 (直到空间被显式释放)。

这也声称是的,您可以使用*alloc 以任何方式分配内存并将其分配给任何指针类型(要求fundamental alignment)。

正如在引用的突出显示部分中您可以看到的那样 - 它通过指定 “用于访问分配的空间中的此类对象或此类对象的数组”来说明连续性。。这也是交换参数的一个原因 - 因为在调用结束时,您将获得一块连续的内存。 (总内存大小由传递的两个参数相乘来指定)。

【讨论】:

  • 我想知道为什么它是这样定义的。例如,为什么与malloc 不同?只是将n * sizeof 替换为n, sizeof
  • @EugeneSh..:这是一个有趣的问题..我在想。
  • 除了归零之外,calloc() 在某些平台上可以分配超过SIZE_MAX,即使nmemb * size 溢出。所以和malloc(nmemb * size)不一样。
  • @chux 那么问题是另一个方向 - 为什么malloc 不遵循相同的方案?
  • 许多长期的 C 函数反映了当时常用实践的折衷,将许多变体实践合并为几个。 (例如,受害者:salloc() 分配堆栈 - 不需要 free())。完全理解为什么往往会引出历史教训,而不是简洁的答案。 @MartinJames 我同意不必要的语言功能,但是一旦功能退出,收回它就非常具有挑战性。顺便说一句:好calloc() 检测乘法溢出。 malloc(size*n) 没有。
猜你喜欢
  • 2016-03-30
  • 1970-01-01
  • 1970-01-01
  • 2020-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-18
  • 2014-08-06
相关资源
最近更新 更多