3

Why is there aligment to 8 bytes (and 16 on 64bit systems)? What are reasons for such alignment?

Example:

int* ptr1 = new int;
int* ptr2 = new int;
int* ptr3 = new int;

cout << ptr1 << " " << ptr2 << " " << ptr3 << endl;
cout << ptr2 - ptr1 << endl;

Outputs:

0x15cbc20 0x15cbc40 0x15cbc60  
8
Elengar
  • 33
  • 4

3 Answers3

3
int* ptr1 = new int;
int* ptr2 = new int;
int* ptr3 = new int;

1st there's no guarantee that these statements will allocate contigous memory addresses regarding the sizeof(int).

What are reasons for such alignment?

Because CPU's have caches to access heap allocated data, and these caches are optimized to use byte aligned access for either 32 or 64 bit pointers, depending on the target architecture.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
1

There is no guarantee that dynamically allocated objects would be stored adjacently at all (even in adjacent aligned address). The fact that your allocator happened to allocate memory 8*sizeof(int) (32 on your system) bytes apart is an implementation detail.

operator new is typically (although not guaranteed to, this is another implementation detail) implemented with using malloc. There is no way to request particular alignment when allocating memory with malloc. That is why it is guaranteed to allocate memory suitably aligned for any built-in type i.e. to sizeof(maxalign_t) boundary. So, for a typical implementation, I would not find an alignment of 8 or 16 bytes unexpected.

eerorika
  • 232,697
  • 12
  • 197
  • 326
1

Actually two things are typically responsible :

  • Alignment (Other answers dealt with this)
  • Bookkeeping information

When you request 4 bytes (for example) of memory, your underlying memory allocator (whatever is used by the selected operator new(...)) may use some extra bytes to store some bookkeeping information. See a good explanation here

The bookkeeping information is usually why delete works without having to tell it the original size of memory requested.

For example:

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;
}

Each memory allocated to you has some backlogged information attached to it. There are many different ways memory allocators work, some have bookkeeping information of a single pointer to some master Structure where memory is managed.

The C++ standard doesn't require successive memory allocations to be contiguous, neither does it specify how much memory "gap" between them.

Community
  • 1
  • 1
WhiZTiM
  • 21,207
  • 4
  • 43
  • 68
  • CPU word is 2 bytes, am I right? So this alignment is not so significant for the overheading size. Or there is some additional alignment, not only to word? – Elengar Mar 05 '17 at 20:28