我听说malloc()
根据分配的类型对齐内存。例如,从书中了解和使用C指针:
分配的内存将根据指针的数据类型进行对齐。例如,一个四字节整数将分配在一个可被4整除的地址边界上。
如果我遵循,这意味着
int *integer=malloc(sizeof(int));
将分配在可被4整除的地址边界上。即使没有在malloc上投射(int *)
。
我在聊天服务器上工作;我读了similar effect struct
s。
我不得不问:从逻辑上讲,为什么地址边界本身可以被整除呢?使用地址n*sizeof(int)
上的整数将一组内存分配到129
曲调有什么问题?
我知道指针算法是如何工作的*(integer+1)
,但我无法弄清楚边界的重要性......
答案 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 访问未对齐的数据! (如果您尝试访问此数据,处理器可能会出现故障)