language is C with gcc compiler
if i make a struct like so
struct test {
char item_1[2];
char item_3[4];
char item_4[2];
char item_5[2];
char item_6[4];
};
and i do a sizeof(struct test) it returns 14(bytes). which is the expected result.
but if i do
struct test {
int16_t item_1;
int32_t item_3;
int16_t item_4;
int16_t item_5;
int32_t item_6;
};
sizeof(struct test) will return something strange like 44. when i debug using gnu ddd i can see inside the structure and see that it all looks normal and all it开发者_如何学Cems have the expected number of bytes.
so why is the sizeof operator returning a unexpected value ?
You have mixed 32/16 bit integers.
int16_t item_1[2]; // 2 * 2 = 4
int32_t item_3[4]; // 4 * 4 = 16
int16_t item_4[2]; // 2 * 2 = 4
int16_t item_5[2]; // 2 * 2 = 4
int32_t item_6[4]; // 4 * 4 = 16
// sum = 44
Compilers may insert padding between struct members, or after the last member. This is normally done to satisfy alignment requirements. For example, an int32_t
object might require 4-byte alignment, so the compiler inserts 2 bytes of padding between the first and second members. The details will vary depending on the platform.
compiler is required to insert padding between structure members to align each member on its type's boundary and to order the structure's members as written. If you reorder them such that the largest members are at the beginning of the structure definition, they will be the same size. But since you're trying it with arrays of char, I'm guessing you don't have the structure's original definition, and you're trying to access some externally defined and created object's fields. In that case, I suggest you either obtain the proper headers or use the char[] version and cast char* to whatever type it really is.
The alignment issue is because modern 32-bit CPU's work in 32-bit word sizes on 32-bit address boundaries. If a 32-bit word on a 32-bit boundary contains 2 16-bit values, this results in extra instructions being required to obtain the correct 16-bits (i.e. masking and shifting so that the correct 16-bits are all that remains). If a 32-bit word is split across a 32-bit boundary then there is even more work to do to retrieve it.
By default the trade-off is to have faster programs and not use the memory as efficiently as possible. If an extra couple of instructions are needed everywhere where a structure member is used then this will probably use more memory than tighter packing the structure saves so whilst not obvious at first it's the correct choice.
If you have a requirement to store structures efficiently (at a cost to performance) then "#pragma pack" allows you to tighter pack members, but it results in bigger slower programs.
http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html
http://www.cplusplus.com/forum/general/14659/
struct test {
int16_t item_1[2]; // 2 * 16 +
int32_t item_3[4]; // 4 * 32 +
int16_t item_4[2]; // 2 * 16 +
int16_t item_5[2]; // 2 * 16 +
int32_t item_6[4]; // 4 * 32
// total = 352
};
352 bits divided by 8 (8 bits go into one byte) is 44 bytes.
精彩评论