为什么Malloc()关心边界对齐?

时间:2014-05-09 23:32:18

标签: c++ c pointers memory-management

我听说malloc()根据分配的类型对齐内存。例如,从书中了解和使用C指针

  

分配的内存将根据指针的数据类型进行对齐。例如,一个四字节整数将分配在一个可被4整除的地址边界上。

如果我遵循,这意味着 int *integer=malloc(sizeof(int));将分配在可被4整除的地址边界上。即使没有在malloc上投射(int *)

我在聊天服务器上工作;我读了similar effect struct s。

我不得不问:从逻辑上讲,为什么地址边界本身可以被整除呢?使用地址n*sizeof(int)上的整数将一组内存分配到129曲调有什么问题?

我知道指针算法是如何工作的*(integer+1),但我无法弄清楚边界的重要性......

6 个答案:

答案 0 :(得分:27)

  

分配的内存将根据指针的数据进行对齐   类型。

如果你在谈论malloc,这是错误的。 malloc并不关心您对数据执行的操作,并会根据最严格的本机实现类型分配内存。

来自标准:

  

如果分配成功,则返回指针,适当地对齐   它可以被分配给指向任何类型的对象的指针   基本对齐要求然后用来访问这样的   对象或分配的空间中的此类对象的数组(直到   空间明确解除分配)

  

逻辑上,为什么地址边界本身很重要   

可分割

由于底层机器的工作原理,访问未对齐的数据可能更昂贵(例如x86)或非法(例如arm)。这使得硬件可以采用快捷方式来提高性能/简化实施。

答案 1 :(得分:10)

在许多处理器中,未对齐的数据将导致“陷阱”或“异常”(这是一种不同于C ++编译器所理解的异常形式。即使在数据不存在时也不会陷阱的处理器上当数据未正确对齐时,它通常较慢(例如,慢两倍)。因此,在编译器/运行时库中确保事物很好地对齐是最好的。

顺便说一句,malloc(通常)不知道你在分配什么。 Insteat,malloc会将所有数据(无论大小是多少)对齐到一些合适的边界,这些边界对于一般数据访问来说“足够好” - 在现代OS /处理器组合中通常为8或16个字节,4个字节在旧系统。

这是因为malloc不会知道您是char* p = malloc(1000);还是double* p = malloc(1000);,所以它必须假设您正在存储double或其他任何项目最大的对齐要求。

答案 2 :(得分:4)

对齐的重要性不是语言问题,而是硬件问题。某些机器无法读取未正确对齐的数据值。其他人可以这样做,但效率较低,例如,需要两次读取才能读取一个未对齐的值。

答案 3 :(得分:4)

书的引用是错误的; malloc返回的内存保证为任何类型正确对齐。即使您编写char *ch = malloc(37);,它仍然会与int或任何其他类型对齐。

你似乎在问"什么是对齐?"如果是这样,那么关于这个问题就有几个问题,例如: here,或来自IBM here的好解释。

答案 4 :(得分:2)

这取决于硬件。即使假设int是32位,malloc(sizeof(int))也可以返回可被1,2或4整除的地址。不同的处理器以不同方式处理未对齐的访问。

处理器不再直接从RAM中读取,这太慢了(需要数百个周期)。因此,当他们抓住RAM时,他们会以大块的方式抓取它,例如一次64个字节。如果您的地址未对齐,则4字节整数可能跨越两个64字节高速缓存行,因此您的处理器必须执行两次加载并修复结果。或许工程师决定构建硬件以修复未对齐的负载是不必要的,因此处理器发出异常信号:程序崩溃,或者操作系统捕获异常并修复操作(数百个浪费的周期) )。

对齐地址意味着您的程序可以很好地与硬件配合使用。

答案 5 :(得分:0)

因为它更快;大多数处理器喜欢对齐的数据。甚至,某些处理器 CAN NOT 访问未对齐的数据! (如果您尝试访问此数据,处理器可能会出现故障)