zoukankan      html  css  js  c++  java
  • 关于sizeof struct

    ASK:The size of my structure is not what I expect it to be。。。

    Answer:This is caused by the fact that the compiler inserts padding in different places for optimization and alignment purposes

    Explanation

    Structure member alignment

    Suppose you have the following structure:

    struct A1 { char a[2]; int b; }; 

    You could think that sizeof(A1) equates to 6, but it doesn’t. It equates to 8. The compiler inserts 2 dummy bytes between members ‘a’ and ‘b’.

    The reason is that the compiler will align member variables to a multiple of the pack size or a multiple of the type size, whichever is smallest.

    The default pack size in visual studio is 8 bytes.

    ‘b’ is of the integer type, which is 4 bytes wide. ‘b’ will be aligned to the minimum of those 2, which is 4 bytes. It doesn’t matter if ‘a’ is 1, 2, 3 or 4 bytes wide. ‘b’ will always be aligned on the same address.

    Structure end padding

    Suppose we swap members ‘a’ and ‘b’:

    struct A2 { int b; char a[2]; }; 

    The compiler places ‘a’ right next to ‘b’ without padding, because the address after ‘b’ is naturally aligned for ‘a’.

    Still, sizeof(A2) equates to 8. The reason is that ‘b’ still needs to be aligned on a multiple of 4 bytes if 2 structures of type A2 are placed in an array.

    If nothing special was done, member ‘b’ of the second structure would be placed right after member ‘a’ of the first structure. This would not a 4 byte multiple but a 2 byte multiple.

    To prevent this, the compiler pads the end of the structure with dummy bytes until the structure size is a multiple of the largest alignment in the structure. That way the alignment for all consecutive structures is valid.

    This can lead to strange situations if you create custom structures without paying attention to these details. This can be illustrated with the following structure if the pack size is left to the default 8 bytes:

    struct A3 { char a; double b; char c; }; 

    ‘a’ is 1 byte wide, and aligned to the start of the structure.

    ‘b’ is 8 bytes wide, but is aligned on the next address multiple of 8 bytes. This means that 7 dummy bytes are inserted between ‘a’ and ‘b’.

    ‘c’ is 1 byte wide, but the structure A3 itself is padded with 7 extra bytes because its size has to be a multiple of 8.

    As a result, the total structure size is a whopping 24 bytes, even though there are only 10 bytes of data inside.

    Programmatically controlling pack size

    It is possible to control structure packing at compile time. That can be done using a pragma directive:

     #pragma pack(push, 1) struct A4 { char a; double b; char c; }; #pragma pack(pop) 

    The first pragma stores the current pack setting and changes it to 1. This will cause all data members to be placed right next to each other, since the minimum of 1 byte and any member size is still 1 byte.

    The structure size for this structure is not 24 anymore, but 10. Of course, since the double value is not 8 byte aligned anymore, read and write operations to it might not be as efficient anymore.

    The second pragma directive will restore the global pack size to its previous setting. This way the local pack size change has no side effects in other parts of the code.

    It is also possible to change the pack size and leave it like that, but that could cause problems in other parts of the code.

    Additional Reading Material

    Packing is explained in detail in the MSDN documentation. Refer to the following article for more information. http://msdn2.microsoft.com/en-us/library/2e70t5y1.aspx

    Acknowledgements

    This FAQ was contributed by Bruno van Dooren.

  • 相关阅读:
    java实现从实体到SQL语句的转换
    Mybatis Plus 入坑(含最新3.X配置)
    Spring cloud config client获取不到配置中心的配置
    Spring Cloud Config-Client 无法获取 Config-Server 在 github 上的配置文件的属性值,竟然是因为
    QMessageBox 的四种用法
    龙芯派二代发布,简化国产软硬件开发难度
    解析Qt元对象系统(五) Q_INVOKABLE与invokeMethod(automatic connection从Qt4.8开始的解释已经与之前不同,发送对象驻足于哪一个线程并不重要,起到决定作用的是接收者对象所驻足的线程以及发射信号(该信号与接受者连接)的线程是不是在同一个线程)good
    解析Qt元对象系统(四) 属性系统(确实比较方便)
    HTML如何让IMG自动适应DIV容器大小
    布隆过滤---判断一个元素在亿级数据中是否存在
  • 原文地址:https://www.cnblogs.com/gaojing/p/1583543.html
Copyright © 2011-2022 走看看