3
votes

I wrote a simple program to test copying bytes from a byte buffer to a structure using memcpy. However I am not getting the results expected.

I allocate a buffer of 100 bytes, and set the values 0, 1, 2...99. I then copy the bytes to a structure that is 16 bytes.

Somewhere byte 0x01 gets lost. I am trying to understand what is happening

#include <stdio.h>
#include <stdint.h>

struct Test {

    uint8_t a;
    uint16_t b;
    uint32_t c;
    uint64_t d;
    uint8_t e;
};

int main(int argc, char** argv) {

    uint8_t buffer[100];
    for (uint8_t i = 0; i < 100; i++) {
        buffer[i] = i;
    }

    struct Test test;
    memcpy(&test, buffer, sizeof(struct Test));

    printf("A is %ld and should be %ld\n", test.a, 0x00);
    printf("B is %ld and should be %ld\n", test.b, 0x0201);
    printf("C is %ld and should be %ld\n", test.c, 0x06050403);
    printf("D is %ld and should be %ld\n", test.d, 0x1413121110090807);
    printf("E is %ld and should be %ld\n", test.e, 0x15);
}

And I get a result of:

A is 0 and should be 0
B is 770 and should be 513
C is 117835012 and should be 100992003
D is 1084818905618843912 and should be 1446519769808832519
E is 16 and should be 21

770 (B value) is bytes 0302, not 0201 (int 513)

1
You need to read about padding in structs.Eugene Sh.
Yes, if you output in hexadecimal %lx it will be easier to see the effect.Weather Vane

1 Answers

5
votes

The reason for this is the compiler has added padding to your struct in order to ensure that b is aligned on a 16-bit boundary. As such, the second byte is unused.

You'll see a much bigger variation if you start re-ordering your struct. Similarly, the 32-bit and 64-bit values will want an alignment suitable to their type. So you can end up with significant "holes" due to padding. Try it!

Often you will see structures that have reserved members (particularly for binary formats), instead of relying on padding.