c – 无法正确地将char数组memcpy到struct

所以我有一个名为packet的结构

struct Packet {
    unsigned int packet_type;
    wchar_t packet_length[128];
    wchar_t file_name[256];
    wchar_t template_name[256];
    wchar_t file_name_list[1024];
    wchar_t file_data[1024];

    void serialize(char * dat) {
        memcpy(dat, this, sizeof(Packet));
    }

    void deserialize(const char * dat) {
        memcpy(this, dat, sizeof(Packet));
    }
};

我正试图从这些数据中剔除

{byte[2692]}
[0]    0       unsigned int packet_type; (4 bytes)
[1]    0
[2]    0
[3]    0
[4]    50 '2'  wchar_t packet_length[128]; (128 bytes)
[3]    0
[5]    54 '6'
[3]    0
[6]    57 '9'
[3]    0
[7]    50 '2'
[8]    0
[...]  0
[132]  112 'p'  wchar_t file_name[256]; (256 bytes)
[133]  0
[134]  104 'h'
[...]  0

但deserialze中的memcpy并没有给我file_name,但它确实给了我packet_length.怎么了?谢谢!

编辑:
所以我现在很清楚,wchar_t占据的空间比我想象的要多;但是,我被告知不要使用memcpy?

我已经编写了这个反序列化方法,它正确地抓取了数据.这会导致安全漏洞吗?

void deserialize(const char * dat) {
        memcpy(&(packet_type), dat, 4);
        memcpy(&(packet_length[0]), dat + 4, 128);
        memcpy(&(file_name[0]), dat + 132, 256);
        memcpy(&(template_name[0]), dat + 388, 256);
        memcpy(&(file_name_list[0]), dat + 644, 1024);
        memcpy(&(file_data[0]), dat + 1668, 1024);
    }
最佳答案
char数组的布局假定wchar_t的大小是两个字节;它不是 – 这里是wchar_t的大小为4的系统的示例,因此Packet的大小是10756,而不是2692字节:(link to a demo).

这就是为什么编辑中的memcpy技巧会出现问题:它假设char []数组中的数据布局与wchar_t []数组的布局相匹配,它可能匹配也可能不匹配.如果您知道数据数组具有以小端格式存储的双字符元素(LSB优先),您可以编写自己的函数将数据从源转换为目标,并调用它以获取部分序列化数据,如这个:

void bytes_to_wchar(wchar_t *dest, const unsigned char* src, size_t length) {
    for (size_t i = 0 ; i != lengt ; i++) {
        dest[i] = src[2*i] | (src[2*i+1] << 8);
    }
}

现在,您可以使用此函数将数据复制到wchar_t数组中,而与目标系统上的wchar_t大小或目标系统的字节顺序无关:

void deserialize(const char * dat) {
    bytes_to_wchar(packet_type,       dat + 0,      4);
    bytes_to_wchar(packet_length[0],  dat + 4,    128);
    bytes_to_wchar(file_name[0],      dat + 132,  256);
    bytes_to_wchar(template_name[0],  dat + 388,  256);
    bytes_to_wchar(file_name_list[0], dat + 644,  1024);
    bytes_to_wchar(file_data[0],      dat + 1668, 1024);
}

当您使用相同的编译器在同一硬件上执行此操作时,从内存中保存数据并将其写回的快捷方式可能会起作用.即使这样,它仍然对您使用的标头和编译器设置中的小调整很敏感.

如果需要复制到结构中的字符数组具有固定布局,则需要编写一个函数来处理该布局,将两字节组转换为wchar_ts,将四字节组转换为无符号整数,依此类推.

转载注明原文:c – 无法正确地将char数组memcpy到struct - 代码日志