user695652
user695652

Reputation: 4275

size of struct-array

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

Answers (6)

Aaron McDaid
Aaron McDaid

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

Keith Thompson
Keith Thompson

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

David Schwartz
David Schwartz

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

Mooing Duck
Mooing Duck

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

Kos
Kos

Reputation: 72319

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.

Upvotes: 5

John Humphreys
John Humphreys

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

Related Questions