1

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?

4
  • 4
    See: en.wikipedia.org/wiki/Data_structure_alignment Commented Dec 20, 2011 at 0:58
  • @user695652: if you're using MSVC, turn the warnings up to /WALL and it will tell you exactly why. Commented Dec 20, 2011 at 0:59
  • 1
    @user695652, What did you expect the size to be? What's your question? Are you surprised that sizeof(A) is 16? Or where you expecting 5*16=80? Commented Dec 20, 2011 at 1:04
  • 2
    Your question would be much more constructive if you told us why you find 16 to be a surprising result. Commented Dec 20, 2011 at 1:21

6 Answers 6

5

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).

Sign up to request clarification or add additional context in comments.

7 Comments

Which structure? An A, or an A[5]? Your answer doesn't explain why the sizeof isn't something like 80.
I answered the question that was asked. Your answer makes a lot of assumptions about the reason the question was asked, and I see nothing in the question to justify those assumptions.
He probably would have done so if the OP had asked why it isn't something like 80. David answered the question precisely and correctly as it was asked. (In my own answer, I indulged in a bit of speculation about what the OP was actually concerned about.)
+1. This is actually the right answer to that specific question which is "why is the sizeof 16?". It's 16 because 16 bytes are required to hold the structure. And, Aaron, you need to work out the difference between a struct structure and a [] array :-)
Everybody, including me, needs to slow down a little. Thanks for the comments.
|
5

Possibly because:

  • you are on a 64-bit platform and char* takes 8 bytes while int and float take 4 bytes,
  • you are on a 32-bit platform and 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.

Comments

4

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.

Comments

2

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.

4 Comments

Do some processors do 8 bit alignment on floats? I haven't heard that (though I'm not saying you're wrong). I just assumed that the pointer was the 8 byte member.
I'm not an expert, but I've been taught before that for some reason 8-byte alignment is used on floats for performance reasons. I wouldn't know what those reasons were though, so maybe we can find a reference somewhere :) But he might just be on 64-bit which would make you definitely more right than me - I definitely slanted mine to assuming he was 32 for some reason (don't know why looking back).
makes sense. Your answer is by far better than mine now though.
I'm actually having trouble finding anything online to back up this 8-byte thought (frankly, I'm having trouble finding anything relevant at all either way - but it's not looking promising :p). I did see a couple places where double was marked to take 8, that might be what I'm flashing back to :/
2

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.

1 Comment

I'll give you 1 for the edit, Aaron, and for suffering the slings and arrows :-)
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.