C memcpy进行结构分配

use*_*470 3 c memcpy

我编写了一个简单的程序来测试使用memcpy将字节从字节缓冲区复制到结构中。但是我没有得到预期的结果。

我分配了100个字节的缓冲区,并将值设置为0、1、2 ... 99。然后,我将字节复制到16字节的结构中。

字节0x01丢失了。我试图了解正在发生的事情

#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);
}
Run Code Online (Sandbox Code Playgroud)

我得到的结果是:

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
Run Code Online (Sandbox Code Playgroud)

770(B值)是字节0302,而不是0201(整数513)

pad*_*ddy 5

这样做的原因是编译器已将填充添加到结构中,以确保b在16位边界上对齐。这样,第二字节未被使用。

如果您开始重新排序结构,将会看到更大的变化。同样,32位和64位值将需要适合其类型的对齐方式。因此,由于填充,您可能会遇到明显的“漏洞”。试试吧!

通常,您会看到具有reserved成员的结构(尤其是对于二进制格式),而不是依赖填充。