Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I am not able to understand how bytes in memory are being mapped into a struct.

ID: 654902 • Letter: I

Question

I am not able to understand how bytes in memory are being mapped into a struct. My machine is a little-endian x86_64. The code was compiled with gcc 4.7.0 from the Win64 mingw32-64 distribution for Win64.

These are contents of the relevant memory fragment:

...450002cf9fe5000040115a9fc0a8fe...

And this is the struct definition:

typedef struct ip4 {
    unsigned int ihl :4;
    unsigned int version :4;
    uint8_t tos;
    uint16_t tot_len;
    uint16_t id;
    uint16_t frag_off; // flags=3 bits, offset=13 bits
    uint8_t ttl;
    uint8_t protocol;
    uint16_t check;
    uint32_t saddr;
    uint32_t daddr;
    /*The options start here. */
} ip4_t;
When a pointer to such an structure (let it be *ip4) is initialized to the starting address of the above pasted memory region, this is what the debugger shows for the struct's fields:

ip4:          address=0x8da36ce
ip4->ihl:     address=0x8da36ce, value=0x5
ip4->version: address=0x8da36ce, value=0x4
ip4->tos:     address=0x8da36d2, value=0x9f
ip4->tot_len: address=0x8da36d4, value=0x0
...
I see how ihl and version are mapped: 4 bytes for a long integer, little-endian. But I don't understand how tos and tot_len are mapped; which bytes in memory correspond to each one of them.

Thank you in advance.

Explanation / Answer

tosis mapped to 0x8da36d2, just 4 bytes after ihl, and it uses the byte at that address for storing the value 9f. The compiler seems to use 16-bit alignment here, so the start of tot_len is two bytes later from 0x8da36d4 to 0x8da36d5, and the value at 0x8da36d3 (which seems to be e5in your example) is just unused garbage.