memcpy混合了struct的内容?

时间:2017-05-04 16:09:48

标签: c file io memcpy

我一直致力于写入R2K对象模块,而且我在将符号表条目写入文件时遇到了麻烦。我一直在尝试使用memcpy将存储在sym_table中的符号表的条目放入一个名为bytes_sym的一个字节整数数组中,然后将其写入文件。它会复制正确的大小,但由于某种原因会混淆字节的位置。这是我的代码:

/*
** symbol table entry
*/    
typedef
struct syment {
    uint32_t flags;      /* flag word */
    uint32_t value;      /* value associated with this symbol */
    uint32_t sym;        /* symbol name's index into string table */
}
    syment_t;

// header->data[8] is the number of symbol table entries
int sym_length = header->data[8] * sizeof(syment_t);

uint8_t bytes_sym[sym_length];

for(int i = 0; i < header->data[8]; i++){
    memcpy(&bytes_sym[i * sizeof(syment_t)], &sym_table[i], sizeof(syment_t));
}
fwrite(bytes_sym, sym_length, 1, file);

// prints the newly copied symbol table section one byte at a time
// I know it's gross to look at, but it's only for testing :p
printf("New Symtab:\n");
for(int i = 0; i < sym_length; i++){
    printf("0x%x ", bytes_sym[i]);
}
printf("\n");

在写入之前,字节值为:

0x0 0x0 0x0 0xb1 0x0 0x40 0x0 0x2c 0x0 0x0 0x0 0x0
0x0 0x0 0x0 0xa3 0x10 0x0 0x0 0x20 0x0 0x0 0x0 0x5
0x0 0x0 0x40 0xb1 0x0 0x40 0x0 0x38 0x0 0x0 0x0 0xb
0x0 0x0 0x0 0xa1 0x0 0x40 0x0 0x14 0x0 0x0 0x0 0x10
0x0 0x0 0x40 0xb1 0x0 0x40 0x0 0x0 0x0 0x0 0x0 0x15
0x0 0x0 0x0 0x67 0x0 0x0 0x0 0x11 0x0 0x0 0x0 0x1f
0x0 0x0 0x0 0xa2 0x10 0x0 0x0 0x0 0x0 0x0 0x0 0x19
0x0 0x0 0x40 0xb1 0x0 0x40 0x0 0x64 0x0 0x0 0x0 0x29
写完后,他们是(不正确,不应该是不同的):

0xb1 0x0 0x0 0x0 0x2c 0x0 0x40 0x0 0x0 0x0 0x0 0x0 
0xa3 0x0 0x0 0x0 0x20 0x0 0x0 0x10 0x5 0x0 0x0 0x0 
0xb1 0x40 0x0 0x0 0x38 0x0 0x40 0x0 0xb 0x0 0x0 0x0 
0xa1 0x0 0x0 0x0 0x14 0x0 0x40 0x0 0x10 0x0 0x0 0x0 
0xb1 0x40 0x0 0x0 0x0 0x0 0x40 0x0 0x15 0x0 0x0 0x0 
0x67 0x0 0x0 0x0 0x11 0x0 0x0 0x0 0x1f 0x0 0x0 0x0 
0xa2 0x0 0x0 0x0 0x0 0x0 0x0 0x10 0x19 0x0 0x0 0x0 
0xb1 0x40 0x0 0x0 0x64 0x0 0x40 0x0 0x29 0x0 0x0 0x0

我无法绕过造成这种情况的原因,所以任何帮助都会非常感激!

1 个答案:

答案 0 :(得分:-3)

好吧,你们完全撒谎memcpy没有弄乱我的数据。在做了一些研究之后,我发现在我的32位对象模块的符号表部分中,这是一个反转每个4字节块中字节顺序的字节序。所以我写了一个小函数来解决它:

///    Flips the bytes in each 4 byte block after the endian flip caused by memcpy
///    @param - the array of bytes
///    @param - the length of the array in bytes
///
void flip_bytes(uint8_t byte_array[], int length){

    uint8_t tmp;
    for(int i = 0; i < length; i++){
            if((i+1) % 4 == 0){

                    // switch the first and last bytes
                    tmp = byte_array[i];
                    byte_array[i] = byte_array[i-3];
                    byte_array[i-3] = tmp;
                    // switch the middle 2 bytes
                    tmp = byte_array[i-1];
                    byte_array[i-1] = byte_array[i-2];
                    byte_array[i-2] = tmp;
            }
    }
}