为什么在分配的变量之间存在16字节差异'地址?

时间:2017-03-05 17:58:03

标签: c++ c++11

为什么有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

3 个答案:

答案 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 ++标准不要求连续的内存分配是连续的,也不要指定它们之间有多少内存“间隙”。