I have an uin16_t
array that I am trying to initialize all values to zero, an interesting thing happens when I reach array index 4. The garbage value in there is 58248, I try and set the value to 0 and it changes the memory address, interestingly by 58248.
Here is an example of what I am doing.
I have a struct declare in my header:
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;
In my source file I have this:
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]);
}
Output looks as expected until index 4:
indx: 3
address: 6415246
value: 0
address: 6415246
value: 0
indx: 4
address: 6415248
value 58248
address: 6357000
Here a seg fault occurs. Interestingly the memory address changes by the same amount as the garbage value that is initially in that array index. I am stumped. I do this similar thing in several other places with no issue at all.
>Solution :
The problem is that my_struct
is smaller than 4 * sizeof(uint16_t)
. The address &struct_instance
only points to enough memory for my_struct
. When indx
reaches 4
struct_pointer->struct_overlay[indx] = 0;
will write outside the bounds of the structure, causing undefind behavior.
If you want memory that’s big enough for both the array and the structure, you need to declare the variable to be the union
type, not one of the member types.
my_struct_union struct_instance;