代码之家  ›  专栏  ›  技术社区  ›  kgbook

关于内存对齐的一些困惑

  •  0
  • kgbook  · 技术社区  · 8 年前
    #define     MCARD_CLS_TYPE_HD           1
    #define     MCARD_SN_LEN                13
    
    typedef struct mcard_ipc_list       
    {                                   
        struct mcard_node *owner;
    
        struct
        {
            struct mcard_ipc_list *next;
            struct mcard_ipc_list *prev;
        } node;
    
        char sn_buf[MCARD_SN_LEN];  //13 byte
    
        struct len_str sn;          //8 byte                            
        struct mcard_smss smss[MCARD_CLS_TYPE_MIN + 1]; //16*3 byte
    } _mcard_ipc_list;
    
    
    struct mcard_smss           *smss = NULL;
    struct mcard_node           *mnode = NULL;
    ...
    smss = mnode->ipc_head.list->smss + MCARD_CLS_TYPE_HD;
    

    问题是 smss 在MFC应用程序中不正确,但在win32控制台应用程序中正常!

    变量的地址 在VS2010的监视窗口中。

    win32控制台应用程序的结果:

    smss                            0x0068af61
    &mnode->ipc_head.list->smss[1]  0x0068af61  
    &mnode->ipc_head.list->smss[0]  0x0068af51 
    mnode->ipc_head.list->sn_buf    0x005aaf3c
    

    MFC应用程序的结果:

    smss                            0x00b1ad54 
    &mnode->ipc_head.list->smss[1]  0x00b1ad51 
    &mnode->ipc_head.list->smss[0]  0x00b1ad41 
    mnode->ipc_head.list->sn_buf    0x00b1ad2c
    

    对于MFC应用程序,很明显 安全管理系统 wa不等于 &mnode->ipc_head.list->smss[1] 但有偏移量 0x3 !

    我们看到了 mnode->ipc_head.list->sn_buf 占据 13 字节,而不是对齐!

    (1)

    #pragma pack(push, 1)
    #pragma pack(pop)
    

    (2)

    #define     MCARD_SN_LEN                16
    

    然而,我仍然困惑于 差异 需要字节对齐时,在win32控制台应用程序和MFC应用程序之间!

    1. 距离 之间 &mnode->ipc_head.list->smss[0] 21 字节 在win32控制台应用程序和MFC应用程序中,而不是 24 字节,因为 (13 + 3) + 8 方法 24 ! 但为什么?

    2. 内存地址 应该在定义变量后确定,当然,它们在定义变量之后已在内存中对齐!和 smss = mnode->ipc_head.list->smss + MCARD_CLS_TYPE_HD; 只是一个 转让声明 , 为什么MFC应用程序中的结果不是 0x00b1ad51 但是 0x00b1ad54

    那么,有谁能帮我吗?


    使现代化 :

    嗯,我写了一个MFC演示来解决第二个问题。

    struct mcard_smss *smss = NULL;
    smss = (struct mcard_smss *)0x00b1ad51;
    

    然而 安全管理系统 我在vs2010的观察窗口中看到的不是 0x00b1ad54 但是 0x00b1ad51 !

    有些东西变了,太神奇了!我不知道为什么

    1 回复  |  直到 8 年前
        1
  •  3
  •   David C. Rankin    8 年前

    从注释继续,因为编译器可以在 结构 ,您可以使用 offsetof 宏( stddef.h )要确定宏中成员的偏移,请执行以下操作:

    size_t offsetof(type, member);
    

    偏移 描述了它的用途并提供了一个示例。

    The macro offsetof() returns the offset of the field member from the
    start of the structure type.
    
    This  macro  is useful because the sizes of the fields that compose a 
    structure can vary across implementations, and compilers may insert 
    different numbers of padding bytes between fields.  Consequently, an 
    element's offset is not necessarily given by the sum of the sizes of 
    the previous elements.
    
    A compiler error will result if member is not aligned to a byte boundary
    (i.e., it is a bit field).
    

    很高兴能帮上忙,如果你还有其他问题,请告诉我。