tags:

views:

219

answers:

4

I have this code

struct Student {
char name[48];
float grade;
int marks[10,5];
char gender;
};

Student s;

Now I have to get the sizeof s

so I added

printf("%d",sizeof(s));

now when I hit compile the result showing is 256

and its wrong because it shoud be 253

as because the size of

char name[48]; ----> 48

and

float grade; -----> 4

and

int marks[10,5]; ------> 200

and

char gender; ------->1

so 48+4+200+1 = 253

so why is it telling me 256?

================================

this part is written after I saw your answers

I learned that

Suppose I have this structure: struct { char a[3]; short int b; long int c; char d[3]; };

So ..

+-------+-------+-------+

|           a           |

+-------+-------+-------+

|       b       |

+-------+-------+-------+-------+

|               c               |

+-------+-------+-------+-------+

|           d           |

+-------+-------+-------+

In the packed'' version, notice how it's at least a little bit hard for you and me to see how the b and c fields wrap around? In a nutshell, it's hard for the processor, too. Therefore, most compilers willpad'' the structure (as if with extra, invisible fields) like this:

+-------+-------+-------+-------+

|           a           | pad1  |

+-------+-------+-------+-------+

|       b       |     pad2      |

+-------+-------+-------+-------+

|               c               |

+-------+-------+-------+-------+

|           d           | pad3  |

+-------+-------+-------+-------+

so if Im having the maximum size is 200 should the padding be like

48 + 152

4 + 196

200 + 0

1 + 199

to make them in a perfect shape

+15  A: 

There may be padding bytes between the members of the struct or at the end of the struct.

In this case, it is likely that there are three bytes of padding at the end of the struct, after the single char member, to ensure that the size of the struct is a multiple of four.

James McNellis
+1: word alignment is definitely a reasonable culprit. http://en.wikipedia.org/wiki/Data_structure_alignment (hiba salem: 1 word = 4 bytes)
Matt Ball
@Bears will eat you: Yes, we should be more worried about bears eating us than 3 bytes extra used space due to alignment issues. ;)
R. Bemrose
@James: There should be no padding between elements, it's a POD type.
GMan
@GMan: "Note: There might therefore be unnamed padding within a POD-struct object, but not at its beginning, as necessary to achieve appropriate alignment." (9.2/17).
James McNellis
@GMan: the compiler is free to put padding between members (even of a POD type) if it needs to or even it it just wants to.
Michael Burr
@James @Michael: Hm, what of 1.7/5 then? I must be understanding "contiguous storage" wrong then. Allowing it does make obvious sense with little thought though.
GMan
@GMan: My interpretation of 1.8/5: The object must occupy a single contiguous block of memory. The members subobjects all have to be contained within that contiguous block, but they themselves do not need to be contiguous (i.e. there can be padding between them, as 9.2/17 says). There are a few interesting discussions on comp.std.c++ if you search for "contiguous bytes."
James McNellis
@James: Ok, thanks for the tip.
GMan
@GMan: also note the difference in language for PODs: "bytes of contiguous storage" in 1.8/5, against arrays: "contiguously-allocated non-empty set of N sub-objects" in 8.3.4/1. I've always taken the latter to mean that the sub-objects have no gaps between them, and the former only to mean that the bytes which make up the object have no gaps between them: sub-objects of PODs aren't "contiguous". Since later-declared class members have higher addresses than earlier ones (9.2/12), alignment demands padding in e.g. `struct A { int a; char b; int c; }` on ARM. c's address cannot be unaligned.
Steve Jessop
+2  A: 
int marks[10,5];

should be

int marks[10][5];

There may also be issues of padding and alignment to consider.

Paul R
+3  A: 

The compiler pads the struct to align to a word boundary. It's easier for the processor to handle chunks of 256 bytes than an odd number like 253.

Bruce Alderman
It has to do with the position of individual elements rather than the size as a whole. If the struct had three chars, and nothing else, the odd size would likely be ignored.
Dennis Zickefoose
@Dennis: The size of the complete struct matters as well, since one can have an array of some struct type and there can be no padding between elements in an array.
James McNellis
That is still based on the alignment requirements of the individual members. I didn't word it well, but what I was trying to get across is that the compiler doesn't want the size to be a multiple of four just for the sake of having a multiple of four. If 2-byte alignment is good enough for int and float, it might pad to a multiple of 2. If float requires 6-byte alignment, it will pad accordingly.
Dennis Zickefoose
It doesn't necessarily align it to a word boundary. It depends on the size of the largest primitive component
Rado
No, it is whatever is neccessary to satisfy the most stringent allignment requirement. This need not correspond to the largest data member.
Dennis Zickefoose
@Dennis Zickefoose: Then how do you explain this result with VC++ 2008: struct{_2B ; _8B;} results in 00 00 ff ffff ff ff ff00 00 00 0000 00 00 00, while struct{_2B; _4B; _4B} results in 00 00 ff ff00 00 00 0000 00 00 00 ?#pragma pack(show)==8 ... for the bytes above, padded bytes are ff since i memsetted the struct to 0xff, then assigned 0 to the individual members
Rado
Implementation defined behavior is implementation defined. I didn't say it can't correspond to the size of the largest member, I said it need not. Its a hardware question.
Dennis Zickefoose
@Dennis Zickefoose: That makes sense ... thanks for clarifying it
Rado
+2  A: 

If using Visual C++, add #pragma pack(1) to the top of your source file to eliminate struct padding. Default for VC++ is 8 byte boundary.

gcc and other compilers will have their own equivalents.

spoulson
Note that this will hurt performance when accessing struct members, and is not probably not worth the 3 bytes you save.
rjh
@rjh: It can have worse effects than that. I've seen Windows API functions fail when passed a LPWSZ that isn't even-aligned.
Steven Sudit
Yes, this is a touchy subject. Having data properly aligned allows hardware processes like DMA to fetch blocks of data at a time. If the struct unnecessarily crosses this boundary, two fetches will need to be made instead. Using pack(1) is handy when you're working with file format structs and are only doing file I/O and need the `sizeof()` operator to give accurate sizes.
spoulson