C 数组在赋值时更改位置

mgr*_*ier 0 c pointers

我有一个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)

这里发生了段错误。有趣的是,内存地址的变化量与最初位于该数组索引中的垃圾值的变化量相同。我很困惑。我在其他几个地方也做了类似的事情,没有任何问题。

Bar*_*mar 5

问题是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)