Mechatrommer’s post answers the question of alignment. None answers the actual question posted. Alignment alone explains padding between elements, not
after the last element.
The answer to the question of why C allocates more memory is: it does, because you tell it to do so. C has no features to allocate structures.
malloc,
calloc and
realloc are unaware of the type being allocated. Each of them receive the number of bytes to allocate. You — the programmer — indicate, how many bytes to allocate. If you think otherwise: stop here, carefully examine the expressions you are using, and what is the meaning of each of them at each step.
What you probably meant to ask is why
sizeof returns 8 instead of 7. In C this is required to fulfil two requirements. An array type is defined as “
continguously allocated nonempty set of objects”. At the same time each object (in array or not) must be aligned. The only way to make this true is if
sizeof returns value compatible with structure’s alignment.
“Because the standard says so” is rarely a satisfying answer. In this case it’s even less satisfying: the same thing applies not only to C and it doesn’t seem like this alignment is always required. Yes, there is a deeper, more technical reason: the way modern memory management is done. I don’t know, how much you learned about memory allocation so far. Is the picture you hold like this: a program wants to allocate 7 bytes of memory, so it asks operating system to give it 7 bytes, and then passes it to the caller? If yes, it’s wrong. Operating systems pass memory to programs in pages: for example on modern Linux systems it’s 4096 bytes. It would also be inefficient and burdensome for a program to constantly ask for single pages, so more often this is done in bunches ranging from megabytes to gigabytes. This address space is then distributed by the allocator. Managing memory can’t be done efficiently, if each time an exact number of bytes is reserved. Allocators keep pools of chunks of pre-defined sizes. E.g. 4 bytes, 16 bytes, 64 bytes, and 1024 bytes.
(1)(2) Then they decide from which chunk to return fit the request best. If you see the problem from this perspective, the extra bytes at the end are becoming irrelevant. They will be allocated anyway, because the memory management simply doesn’t offer higher granularity.
(1) The actual numbers and their count differ between environments. You may see
jemalloc paper for an overview of one of such systems.
(2) Note that in C
sizeof still returns what is indicated by alignment, not by how much memory the allocator may need to reserve.