我有一个数组,每个元素可以是uint16_t类型或者是一对uint8_t类型。
它的元素被定义为uint16_t和2个uint8_t的子数组的联合体。
不幸的是,编译器(MicroChip XC16)为这个数组分配了两倍于应该分配的内存。
typedef union {
uint16_t u16; // As uint16_t
uint8_t u8[2]; // As uint8_t
} my_array_t;
my_array_t my_array[1]; // 1 word array, for testing
my_array[0].u8[0] = 1;
my_array[0].u8[1] = 2;
uint8_t byte_0 = my_array[0].u8[0]; // Gets 0x01
uint8_t byte_1 = my_array[0].u8[1]; // Gets 0x02
uint16_t byte_0 = my_array[0].u16; // Gets 0x0201
编译器分配了4个字节,而不是应该的2个字节。
解决方法:如果我将结构体更改为:
typedef union {
uint16_t u16; // As uint16_t
uint8_t u8[1]; // As uint8_t
} my_array_t;
编译器按照应有的方式分配了2个字节,但这是错误的。
my_array[0].u8[1] = 2;
虽然它仍能正常工作:
uint8_t byte_1 = my_array[0].u8[1]; // Gets 0x02
除了调试器不显示其值的不便之外。
问题:我应该使用解决方法,还是使用更好的解决方案?
请参考先前对此进行的讨论,其中提出了上述解决方案。
编辑。
根据EOF的建议(下面),我检查了sizeof。
在解决方法之前:
sizeof(my_array_t) // Is 4
sizeof(my_array[0]) // Is 4
sizeof(my_array[0].u8) // Is 2
解决方法后:
sizeof(my_array_t) // Is 2
sizeof(my_array[0]) // Is 2
sizeof(my_array[0].u8) // Is 2
这可能意味着这是一个编译器错误。
sizeof(union_x) != sizeof(union_x.largest_member)
,那对我来说看起来像是编译器的错误。 - EOFCHAR_BIT
的值,您需要#include <limits.h>
。另外,sizeof(uint8_t)
是多少?如果不是1
,那么我们就有问题了。 - EOFsizeof(my_array[0].u8) == 2
。那只是一个uint8_t
,所以它应该有一个sizeof(uint8_t) == 1
。 - EOF