为什么有8个字节(和64位系统上的16个)的对齐?这种对齐的原因是什么?
示例:
int* ptr1 = new int;
int* ptr2 = new int;
int* ptr3 = new int;
cout << ptr1 << " " << ptr2 << " " << ptr3 << endl;
cout << ptr2 - ptr1 << endl;
输出:
0x15cbc20 0x15cbc40 0x15cbc60
8
答案 0 :(得分:3)
int* ptr1 = new int;
int* ptr2 = new int;
int* ptr3 = new int;
第1,不能保证这些语句会分配关于sizeof(int)
的重要内存地址。
这种对齐的原因是什么?
因为CPU具有访问堆分配数据的高速缓存,并且这些高速缓存经过优化,可以对32位或64位指针使用字节对齐访问,具体取决于目标体系结构。
答案 1 :(得分:1)
无法保证动态分配的对象完全相邻存储(即使在相邻的对齐地址中)。您的分配器碰巧分配内存8*sizeof(int)
(系统上的32个)字节的事实是一个实现细节。
operator new
通常(虽然不能保证,这是另一个实现细节)使用malloc
实现。在使用malloc
分配内存时,无法请求特定对齐。这就是为什么保证为任何内置类型(即sizeof(maxalign_t)
边界)分配适当对齐的内存的原因。因此,对于典型的实现,我不会发现意外的8或16字节对齐。
答案 2 :(得分:1)
实际上有两件事情通常负责:
当您请求4个字节(例如)的内存时,您的底层内存分配器(所选delete
使用的任何内容)可能会使用一些额外的字节来存储一些簿记信息。请参阅一个很好的解释here
簿记信息通常是void* Malloc(std::size_t size){
//Allocator searches for free memory
auto FreeList = GetNextFreeNodeOfAtLeast(size + 16);
//Rounds the requested size to the ceil of CPU word size
size = RoundToWordAlignment(size);
//Allocate with an extra 16 bytes for bookkeeping
void* Memory = FreeList->Allocate(size + 16);
//Use the Upper 16bytes... some implementations use lower..
auto info = static_cast<MallocInformation*>(Memory + size);
//Create an Info object so that `Free` or operator delete can use to free memory
new(info) MallocInformation(size, FreeList, ....);
//Return the Memory
return Memory;
}
工作的原因,而不必告诉它原始请求的内存大小。
例如:
INTERPOLATE PREVIOUS VALUE
分配给您的每个内存都附有一些积压信息。内存分配器有许多不同的工作方式,有些具有指向内存管理的主结构的单个指针的簿记信息。
C ++标准不要求连续的内存分配是连续的,也不要指定它们之间有多少内存“间隙”。