#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 的监 window 口中看到了变量的地址。
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 应用程序,很明显 smss
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 应用程序之间的区别感到困惑!
问题:
mnode->ipc_head.list->sn_buf
之间的距离和&mnode->ipc_head.list->smss[0]
是21
字节 在 win32 控制台应用程序和 MFC 应用程序中,不是24
字节,因为(13 + 3) + 8
表示24
!但为什么呢?内存地址在变量定义后应该是一定的,当然在变量定义后它们已经在内存中对齐了!和
smss = mnode->ipc_head.list->smss + MCARD_CLS_TYPE_HD;
只是一个赋值语句, 为什么 MFC 应用程序中的结果不是0x00b1ad51
但是0x00b1ad54
?而且这种现象是可以重现的!
那么,如果有人可以帮助我呢?
更新:
嗯,我写了一个 MFC 演示来解决第二个问题。
struct mcard_smss *smss = NULL;
smss = (struct mcard_smss *)0x00b1ad51;
但是,smss
的值我在 vs2010 的监 window 口中看到不是 0x00b1ad54
但是0x00b1ad51
!
有些变化和惊人!不知道为什么
最佳答案
继续评论,因为编译器可以在 struct 中设置字段的大小和填充,您可以使用 offsetof
宏(stddef.h
) 来确定成员在宏中的偏移量:
size_t offsetof(type, member);
offsetof
的手册页描述了它的用法并提供了示例。
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).
很高兴对您有所帮助,如果您还有其他问题,请告诉我。
关于c - 关于内存对齐的一些困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38965992/