#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应用,显然
smss
wa不等于&mnode->ipc_head.list->smss[1]
,但具有偏移量0x3
!我们看到
mnode->ipc_head.list->sn_buf
占用13
字节,而不是对齐!我已经解决了这个问题,有两种方法:
(一)
#pragma pack(push, 1)
#pragma pack(pop)
(二)
#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;
不过,我在vs2010的观察窗口中看到的
smss
值不是0x00b1ad54
而是0x00b1ad51
!有些东西变了,很神奇!我不知道为什么
最佳答案
从注释继续,因为编译器可以设置结构中字段的大小和填充,所以可以使用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/