malloc(1)的对齐要求是什么?

3
我听说,成功调用malloc()会返回一个适合任何类型的指针。然而,要求malloc(1)返回一个比1更大值对齐的指针似乎是无用和浪费的,因为没有比char更大的对象可以存储到该块中。
对于malloc(1)malloc(2)等,对齐要求是什么?
如果对齐要求大于分配的大小,这样的要求的理由是什么?
1个回答

4
在C标准中,malloc函数的定义简洁,没有明确规定任何关于对齐的内容。下面是摘自C23标准的概要,其与之前版本基本相似,只有章节编号发生了变化:

7.24.3.6 The malloc function

Synopsis

#include <stdlib.h>
void *malloc(size_t size);

Description

The malloc function allocates space for an object whose size is specified by size and whose representation is indeterminate.

Returns

The malloc function returns either a null pointer or a pointer to the allocated space.

关于块对齐要求,直到C17为止,这在父章节的开头被指定如下:
7.22.3 内存管理函数 [...] 如果分配成功,则返回的指针将适当地对齐,以便将其赋值给具有基本对齐要求的任何类型对象的指针,并用于访问该对象或该对象数组中的对象(直至显式释放空间)。
这意味着对于所有的基本类型,如int、long、long long等,malloc(1)必须正确对齐,并且对于在分配的空间中访问这些对象存在一定的歧义。
作为一个缺陷进行了报告,这个问题在C23中得到了讨论,并且文本已经修正以放宽此要求并澄清这个歧义(重点是我的)。
7.24.3 内存管理函数 [...] 如果分配成功,则返回的指针将适当地对齐,以便可以将其赋值给具有基本对齐要求且大小小于或等于所请求大小的任何类型对象的指针。然后,它可以用于访问在分配的空间中的此类对象或此类对象的数组(直到显式释放该空间)。
这个修正是受欢迎的:从 C23 开始,malloc(1) 不再有对齐要求,并且连续调用 malloc(1) 可能会返回一个字节包装数组中连续的地址。同样,malloc(2) 不再需要适当对齐以适应大于 2 的大小的对象。malloc(3) 将适当对齐于大多数架构上的 2 字节对象,例如 short 等。
这可能会对利用原始对齐要求在malloc()返回的对象指针的低位存储标签的包造成问题。在这种系统上,传递给malloc的大小必须大于或等于2n,其中n是标签中的位数,通常限制为3或4。更好的解决方案是使用aligned_malloc(),可以指定和测试对齐要求。
还要注意,calloc(4, 1)返回的块的对齐要求为4,因为分配的大小是参数的乘积,第一个参数是要为其分配空间的元素数量,第二个参数是元素大小。因此,程序员不需要了解参数的精确语义。请注意,在其他接受这些参数的C库函数(如fread()fwrite()qsort()bsearch())中,nelemssize的顺序不同。 realloc()遵循相同的要求:减小块的大小可能会产生具有较弱对齐的不同指针。

1
关于calloc(a,b)和“小于或等于所请求的_size_”,在我看来,_size_是a*b,如果需要可以使用扩展数学。 - chux - Reinstate Monica
1
关于 calloc(a, b) 和 "小于或等于所请求的 size",在我看来,sizea*b,如果需要使用扩展数学。 - chux - Reinstate Monica
1
@chux-ReinstateMonica:我同意你的观点。我会修改答案。 - chqrlie
1
@chux-ReinstateMonica:我同意你的观点。我会修改答案。 - chqrlie
1
@WeatherVane 我看不出你从那个句子中得出的那种解释。事实正好相反。分配大小限制了对齐要求,而不是扩大了它。 - Gerhardh
显示剩余20条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接