我有一个uin16_t数组,我试图将所有值初始化为零,当我到达数组索引 4 时,发生了一件有趣的事情。其中的垃圾值是 58248,我尝试将该值设置为 0,有趣的是,它更改了内存地址通过 58248。
这是我正在做的一个例子。
我的标头中有一个结构声明:
typedef struct my_struct
{
//various struct members
} my_struct;
typedef union my_struct_union
{
my_struct struct_instance;
uint16_t struct_overlay[6];
} my_struct_union
extern my_struct_union *struct_pointer;
extern my_struct struct_instance;
Run Code Online (Sandbox Code Playgroud)
在我的源文件中我有这个:
my_struct_union *struct_pointer;
my_struct struct_instance;
void init_struct()
{
struct_pointer = (my_struct_union *)&struct_instance;
for(uint16_t indx = 0; indx < 6; indx++)
{
printf("indx: %d", indx);
printf("address: %d", &struct_pointer->struct_overlay[indx]);
printf("value: %d", struct_pointer->struct_overlay[indx]);
struct_pointer->struct_overlay[indx] = 0;
printf("address: %d", &struct_pointer->struct_overlay[indx]);
printf("value: %d", struct_pointer->struct_overlay[indx]);
}
Run Code Online (Sandbox Code Playgroud)
在索引 4 之前,输出看起来与预期一致:
indx: 3
address: 6415246
value: 0
address: 6415246
value: 0
indx: 4
address: 6415248
value 58248
address: 6357000
Run Code Online (Sandbox Code Playgroud)
这里发生了段错误。有趣的是,内存地址的变化量与最初位于该数组索引中的垃圾值的变化量相同。我很困惑。我在其他几个地方也做了类似的事情,没有任何问题。
问题是my_struct小于4 * sizeof(uint16_t)。该地址&struct_instance仅指向足够的内存my_struct。当indx达到4
struct_pointer->struct_overlay[indx] = 0;
Run Code Online (Sandbox Code Playgroud)
将在结构的边界之外写入,导致未定义行为。
如果您想要足够大的内存来容纳数组和结构体,则需要将变量声明为类型union,而不是成员类型之一。
my_struct_union struct_instance;
Run Code Online (Sandbox Code Playgroud)