Reputation: 4275
If I have a struct A defined as:
struct A {
char* c;
float f;
int i;
};
and an array
A col[5];
then why is
sizeof(*(col+0))
16?
Upvotes: 1
Views: 9305
Reputation: 27183
Edit: There seem to be two parts to this question. "Why is sizeof(A)
equal to 16?" On balance, I see now that this is probably the question that was intended. Instead I am answering the second part, i.e. "Why is sizeof(*(col+0)) == sizeof(A)
?"
col
is an array. col + 0
is meaningless for arrays, so the compiler must convert col
to a pointer first. Then col
is effectively just an A*
. Adding zero to a pointer changes nothing. Finally, you dereference it with *
and are left with a simple A
of size 16.
In short, sizeof(A) == sizeof(*(col+0))
PS: I have not addressed the question "Why does that one element of the array take up 16 bytes?" Others have answered that well.
Upvotes: 2
Reputation: 263627
For starters, your original declaration was incorrect (this has now been fixed in a question edit). A
is the name of the type; to declare an array named col
, you want
A col[5];
not
col A[5];
sizeof(*(col+0))
is the same as sizeof col[0]
, which is the same as sizeof (A)
.
It's 16 because that's the size of that structure, for the compiler and system you're using (you haven't mentioned what it is).
I take it from the question that you were expecting something different, but you didn't say so.
Compilers may insert padding bytes between members, or after the last member, to ensure that each member is aligned properly. I find 16 bytes to be an unsurprising size for that structure on a 64-bit system -- and in this particular case, it's probably that no padding is even required.
And in case you weren't aware, sizeof
yields a result in bytes, where a byte is usually (but not always) 8 bits.
Upvotes: 4
Reputation: 182875
On your platform, 16 bytes are required to hold that structure, the structure being of type A
.
You should keep in mind that *(col+0)
is identical to col[0]
so it's only one of the structure, not the entire array of them. If you wanted the size of the array, you would use sizeof(col)
.
Upvotes: 5
Reputation: 66981
On a modern x86-64 processor, char*
is 8 bytes, float
is 4 bytes, int
is 4 bytes. So the sizes of the members added together is 16. What else would you be expecting? Did someone tell you a pointer is 4 bytes? Because that's only true for x86-32.
Upvotes: 0
Reputation: 72319
Possibly because:
char*
takes 8 bytes while int
and float
take 4 bytes,char*
takes 4 bytes but your compiler decided that the array would be faster if it dropped 4 bytes of padding there. Padding can be controlled on most compilers by #pragma pack(push,1) and #pragma pack(pop) respectively. If you want to be sure, you can use offsetof
(on GCC) or create an object and examine the addresses of its member fields to inspect which fields got actually padded and how much.
Upvotes: 5
Reputation: 39354
Your problem is most likely that your processor platform uses 8-byte alignment on floats. So, your char* will take 4 (assuming you're on a 32-bit system) since it's a pointer which is an address. Your float will take 8, and your int will take another 4 which totals 16 bytes.
Compilers will often make certain types align on certain byte boundaries in order to speed up computation on the hardware platform in use.
For example, if you did:
struct x {
char y;
int z;
};
Your system would (probably) say the size of x was 8, padding the char out to an int inside the structure.
You can add pragmas (implementation dependent) to stop this:
#pragma pack(1)
struct x {
char y;
int z;
};
#pragma pack(0)
which would make the size of this equal to 5.
Upvotes: 2