How does sizeof calculate the size of structures

后端 未结 6 1874
有刺的猬
有刺的猬 2020-12-16 15:37

I know that a char and an int are calculated as being 8 bytes on 32 bit architectures due to alignment, but I recently came across a situation where a structure with 3 short

相关标签:
6条回答
  • 2020-12-16 16:18

    This link should help: http://en.wikipedia.org/wiki/Data_structure_alignment

    In ThreeShorts all members are two byte aligned.

    0 讨论(0)
  • 2020-12-16 16:20

    That's because int is 4 bytes, and has to be aligned to a 4-bytes boundary. This means that ANY struct containing an int also has to be aligned to at least 4-bytes.

    On the other hand, short is 2 bytes, and needs alignment only to a 2-bytes boundary. If a struct containing shorts does not contain anything that needs a larger alignment, the struct will also be aligned to 2-bytes.

    0 讨论(0)
  • 2020-12-16 16:32

    It's entirely implementation-dependent, but presumably if your system can access any of the three shorts in the struct without worrying about the alignment, it can access any short, and hence any data member, in an array of ThreeShorts without worrying about alignment. Therefore there is no need to align the structs more strictly.

    For the IntAndChar example, int presumably has size 4 and the implementation is concerned with its alignment. To ensure that every int member in an array of IntAndChar is properly aligned, the struct must be padded.

    The sizeof an array T[n] is exactly defined as sizeof(T) * n.

    0 讨论(0)
  • 2020-12-16 16:38

    I don't know where you get the idea about char or int being calculated as "8 bytes". No, every type is calculated in accordance with its size: char as 1, int as 4 on a 32-bit platform (not 8, but 4). Alignment requirement for each type is normally the same as its size (although it doesn't have to be).

    For this reason, when the structure contains the members of the same type, the total size of that structure will normally be the exact sum of the sizes of its members: a structure of 3 chars will have size 3, and the structure of two ints will have size 8.

    Apparently type short on your platform has size 2, so, expectedly, a structure of 3 shorts has size 6, which is exactly what you observe.

    However, when your structure contains members of different types, then the difference between alignment requirements of different types comes into play. If the alignment requirement of the next field is stricter than the alignment requirement of the previous field, the compiler might have to add some padding bytes between these fields (to properly align the next member), which will affect the final size of the struct. Also, the compiler might have to add some extra padding bytes after the last member of the structure to satisfy alignment requirements in an array.

    For example, a structure that looks as follows

    struct S {
      char c;
      int i;
    };
    

    will most likely occupy 8 bytes on your platform because of the need for 3 padding bytes after the char member. Note, char counts as 1, int as 4 and the extra 3 padding bytes between them make it 8.

    Note also that this might easily introduce the dependency of the final size of the structure on the order in which the members are declared. For example, this structure

    struct S1 {
      char c1;
      int i;
      char c2;
    };
    

    on your platform will probably have size 12, while this one

    struct S2 {
      int i;
      char c1;
      char c2;
    };
    

    will occupy only 8 bytes. This last example is intended to illustrate that the final size of the structure cannot be expressed in terms of how many bytes each member "counts" for. The relationships between the members are also important.

    0 讨论(0)
  • 2020-12-16 16:38

    Yep, I had the same issue. I have the following structure

    struct Node{
        short digit;
        Node* next;
    };
        cout<<":"<<sizeof(Node)<<":"<<sizeof(short)<<":"<<sizeof(Node*)<<endl;
    

    This gives me ::8:2:4 ?? why is the total sum for the structure = 8, but individual elements don't sum up?? This is because of memory alignment, the memory is padded with extra 2 bytes for alignment. Thanks

    0 讨论(0)
  • 2020-12-16 16:42

    This really puzzles me, why isn't alignment enforced for t

    What alignment do you want it to have ?

    Shorts can be aligned on 2 byte boundaries with no ill effects(assuming common x86 compilers all over here..). So if you create an array of struct ThreeeShorts , that struct having a size of 6 is fine, as any elements in such an array will start on a 2 byte boundary.

    Your struct IntAndChar contains an int, ints wants 4 byte alignment, so if you create an array of struct IntAndChar the size have to be 8 for the next element to be aligned on a 4 byte boundary.

    If we didn't consider arrays, it wouldn't matter much if struct IntAndChar were 5 bytes long, the compiler would just allocate it starting on a 4 byte boundary when you create one one the stack, or use it as a compound member in another struct.

    You can always get the number of elements in an array by doing sizeof(arrayofT)/sizeof(T), and array elements are guaranteed to be stored adjacently, such that the n'th element can be retreived by stepping N*sizeof(arrayelementtype) bytes from the start, and that's the main reason you'll see structs being padded at the end.

    0 讨论(0)
提交回复
热议问题