Can someone explain to me why it prints these values? I can understand why 4 but not the others.
The array uint8_t bytes[32];
is uninitialized. The write *i = 0x01020304;
only updates items 12, 13, 14, 15. Assuming that this is a local scope array, then the rest of the data contains indeterminate values ("garbage"). Reading a variable with indeterminate value gives unspecified results on most systems - you can get any value and the program need not be consistent about it. The most common is that you get some random crap value that happened to sit in that memory cell since earlier execution.
(On some exotic systems, reading an indeterminate value could result in something called trap representation, meaning possible program crash & undefined behavior.)
The 4
you see comes from your system using a little endian CPU, where the number 0x01020304
is stored like [12]=04, [13]=03 and so on, least significant byte on the lowest address. Other CPUs with big endian store numbers in the opposite order and then you'd get index [12]=01 instead.
However, the conversion from uint8_t
to uint32_t
is fishy in itself:
(uint32_t *)&bytes[12];
There are two big undefined behavior problems with this line:
The data could be misaligned (it wasn't in this specific case) or otherwise not presentatble as the target type (unlikely in case of signed integers, very likely in pretty much every other case).
This is also a violation of the C type system ("strict aliasing violation", an advanced topic What is the strict aliasing rule?) which means that the compiler might end up drawing wrong conclusions about what's stored at a certain memory location upon generating the machine code.
Generally speaking, we cannot meaninfully reason about the results of a program containing undefined behavior, nor about one containing reliance on unspecified behavior. See What is undefined behavior and how does it work?.