这个问题与我在此分享的上一个问题密切相关。但是...
我有一个相当大的项目,正在对其进行单元测试和集成测试。不幸的是,除了细小的片段之外,我无法共享代码,而无论如何,这都是要共享的大型项目。
我会尽力总结一下... 类型定义如下:
typedef struct {
s32 s32IntLimitHigh;
s32 s32IntLimitLow;
s32 s32RegLimitHigh;
s32 s32RegLimitLow;
u16 u16IntGain;
u16 u16PropGain;
u16 u16IntStep;
BOOL BOOLFreeze;
} structPIreg;
单个成员的类型通过其名称非常清楚。
定义了两个数组,如下所示:
structPIreg expected_VectParPI[VECT_PI_LENGTH];
structPIreg VectParPI[VECT_PI_LENGTH];
因为它用于单元测试,所以我具有原始变量及其期望值。
数组由8个元素组成。
sizeof (VectParPI[1]) is 29 :
4 * s32 + 3 * u16 + BOOL = 4 * 4 + 3 * 4 + 1 = 29
u16在原始计算机上是16位,在x86架构上是32位。
我编译,测试运行,并且得到奇怪的结果。 因此,我开始进行调试会话,这里的事情变得更加奇怪。
现在,问题在于两个变量的结构大小似乎不同。 而且我在调试器上看到的是一致的。
我将张贴两张变量监视窗口的图片,以使您理解。 在此监视窗口中,我计算两个数组的第二个和第一个元素之间的字节偏移量。
(char*)&VectParPI[1]-(char*)&VectParPI[0] long 32
(char*)&expected_VectParPI[1]-(char*)&expected_VectParPI[0] long 29
如您所见,偏移量是不同的。 但是我不知道为什么。 在目标文件中,相同类型的两个不同变量的偏移量/大小如何不同?
更有意思的是,当我启动调试器并且gdb在main上暂停时,这两个大小是正确的(每个29个)。 比我在某处设置断点,并且在达到断点时,我看到的大小分别为32和29。
如何更改内存地址? 就像结构在内存中转移一样。 我只是不知道为什么。。。
作为我梦dream以求的“证明”,我附加了与以前相同的观察窗口。 您会看到eclipse / gdb以黄色突出显示了大小和偏移量,因为在某些时候它们已从29变为32。 真有趣....:)
答案 0 :(得分:0)
4 * s32 + 3 * u16 + BOOL = 4 * 4 + 3 * 4 + 1 = 29
这不是此结构预期的sizeof
的 。由于填充原因,预期的sizeof
为32。
获得29
的原因是该结构具有__attribute__((packed))
,而获得两个不同大小的事实意味着您的某些编译单元具有packed
属性,其他人没有。
这违反了一个定义规则和未定义的行为。
您需要找到此packed
的来源,并使它在整个程序中保持一致。