I tried to populate an array of structs defined as follows:
typedef struct{
char directive[5];
}directive_nfo_t;
By using the following:
directive_nfo_t directive_list[]=
{
{"ALIGN"},{"ASCII"},{"BSS"},{"BYTE"},{"END"},{"EQU"},{"ORG"}
};
To my surprise, the first few elements were corrupted like so:
[0]= ALIGNASCIIBSS
[1]= ASCIIBSS
[2]= BSS
...
Until I made the following change:
typedef struct{
char directive[6]; <-- made char array +1
}directive_nfo_t;
Then the first few arrays were correct like so:
[0]= ALIGN
[1]= ASCII
[2]= BSS
...
My question is what happens in the background to explain this behavior? Regards.
When you explicitly initialize a char
array as string literal in the way you do:
char some_array[] = {"ALIGN"};
the compiler actually populates the 0th to 4th "position" (total of 5 positions) with the characters inside quotation marks, but also the fifth position with \0
without requiring you do it explicitly (if it has space enough). So the size equals 6. You exceed the boundaries if you don't count the \0
character into the size calculation and restrict the size to 5
. Compiler would omit the terminating character.
In your case it looks as if the first element of the next member "overwrote" what should have been the omitted \0
character of the previous, since you haven't reserved a place for it. In fact the "mechanics of populating the array" boils down to the compiler writing as much data as could fit inside the boundaries. The address of the first position of the next member string logically corresponds to your assignment, although the \0
from the previous is missing.
Since your printf()
format tag was %s
, the function printed the characters until it reached the first \0
character, which is in fact undefined behavior.
That's why
char directive[6];
was correct size assignment in your code.