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.