The second question is implementation (and this is actually the first, but I will show you why you get the gap that you get independently). Your platform is apparently 64-bit, and therefore your data pointers are also (64-bit). In doing so, we look into structures.
stru_12
typedef struct { int i; char *str; } stru_12;
This is aligned, so str always gets to an 8-byte boundary, including in a continuous sequence (array). To do this, 4 bytes of padding are entered between i and str .
0x0000 i - length=4 0x0004 pad - length=4 0x0008 ptr - length=8 ====================== Total 16
An array of them will always have ptr at the 8-byte boundary if the array starts with the same one (which it will be). Since adding padding between i and str also caused the structure to be a multiple of 8, no extra padding is required outside of this.
stru_13
Now let's see how this is achieved using this:
typedef struct { int i; char *str; char c; } stru_13;
The same addition will be used between i and str to place str once on the 8-byte boundary, but adding c complicates the situation. To achieve the goal of pointers that are always at 8-byte boundaries (including the sequence / array of these structures), the structure requires filling the tail, but how much? Well, I hope that obviously the total size of the structure should be a multiple of 8 to ensure that any built-in pointers (which are also a multiple of 8) are correctly aligned. In this case, seven bytes of tail padding are added to bring the size to 24 bytes:
0x0000 i - length=4 0x0004 pad - length=4 0x0008 ptr - length=8 0x0010 c - length=1 0x0011 pad - length=7 ====================== Total 24
stru_13 (part of deux)
So try this one. What would you think that the same fields that we had before, but ordered differently, would lead to:
typedef struct { char *str; int i; char c; } stru_13;
Well, we know that we want str on an 8-byte border and i on a 4-byte border, and, frankly, about it c (always the bride) p>
0x0000 ptr - length=8 0x0008 i - length=4 0x000c c - length=1 0x000d pad - length=3 ====================== Total 16
Run this, although your test program, and you will see that it is laid out, as we said above. It reduces to 16 bytes. All we did was change the order to a more space-friendly layout that still supports our requirements, and we reduced the default representation by 8 bytes (one third of the original structure with the previous layout). To say that it is important to take away from everyone would be an understatement.