malloc如何理解对齐?

Cha*_*ang 47 c c++ memory-alignment

以下摘录自此处

pw = (widget *)malloc(sizeof(widget));
Run Code Online (Sandbox Code Playgroud)

分配原始存储.实际上,malloc调用分配的存储空间足够大并且适当地对齐以容纳类型为widget 的对象

他还说,从草本植物中看到快速的pImpl,他说:

对齐.任何内存对齐.保证通过new或malloc动态分配的任何内存都可以正确地对齐任何类型的对象,但是没有动态分配的缓冲区没有这样的保证

我对此感到好奇,malloc如何知道自定义类型的对齐方式?

Ker*_* SB 46

对齐要求是递归的:任何对齐struct都只是其任何成员的最大对齐,这是递归理解的.

例如,假设每个基本类型的对齐等于它的大小(通常并不总是这样),它struct X { int; char; double; }具有对齐double,并且它将被填充为double的大小的倍数(例如4(int), 1(字符),3(填充),8(双)).在struct Y { int; X; float; }具有的取向X,这是最大的,等于所述对准double,并且Y被相应地布置:4(INT),4(填充),16(X),4(浮动),4(填充).

(所有数字只是示例,可能与您的机器不同.)

因此,通过将其分解为基本类型,我们只需要知道一些基本的对齐,其中有一个众所周知的最大.C++甚至定义了一种类型,max_align_t其对齐方式最大的对齐方式.

所有malloc()需要做的就是选择一个该值的倍数的地址.

  • 需要指出的关键是,这不包括可能过度对齐数据的编译器自定义“align”指令。 (3认同)
  • 虽然如果你使用它们已经超出了标准的范围,请注意以这种方式分配的内存可能*不会*满足某些平台上可用作扩展的构建类型(如_m256)的对齐要求. (3认同)
  • 当您通过“ alignas”指定一个比原始数据类型的最大对齐方式大的自定义对齐方式时,会发生什么? (2认同)
  • @Curious:对扩展对齐的支持是实现定义的。 (2认同)
  • `malloc` 没有关于它分配的类型的信息;唯一的参数是分配的内存的大小。手册页正确地指出了这一点:分配的内存是对齐的,以便它可以用于任何数据类型,即对齐方式对于所有类型都是相同的。 (2认同)

rua*_*akh 22

我认为Herb Sutter引用中最相关的部分是我用粗体标记的部分:

对准.任何内存对齐.保证通过new或malloc动态分配的任何内存都可以正确地对齐任何类型的对象,但是没有动态分配的缓冲区没有这样的保证

它不必知道你有什么类型,因为它对齐任何类型.在任何给定的系统上,都有一个必要或有意义的最大对齐大小; 例如,具有四字节字的系统可能最多具有四字节对齐.

这也被明确malloc(3)手册页,它说部分:

malloc()calloc()函数返回一个指针,该对齐适当分配的内存用于任何类型的变量.

  • 什么是任何变量的含义?它没有回答我的问题.这是否意味着malloc将始终在任何给定系统中使用最大对齐大小,对吧? (3认同)
  • @Chang:有效,是的.还要注意,引用是错误的.在分配`char`或`unsigned char`时,`new`只保证有"任意"对齐.对于其他人,它可能具有较小的对齐. (2认同)

Gre*_*ill 5

唯一malloc()可以使用的信息是传递给它的请求的大小.通常,它可能会执行某些操作,例如将传递的大小向上舍入为最接近的2(或更大)幂,并根据该值对齐内存.对齐值可能还有一个上限,例如8个字节.

以上是一个假设的讨论,实际的实现取决于您正在使用的机器架构和运行时库.也许你malloc()总是返回8字节对齐的块,它永远不会做任何不同的事情.

  • 总而言之,`malloc`使用'最坏情况'对齐,因为它没有更好的了解。这是否意味着`calloc`会更聪明,因为它需要两个参数,对象数量和单个对象的大小? (2认同)