2017-05-04 75 views
0

我一直在寫R2K對象模塊,並且在符號表條目寫入文件時遇到了麻煩。我一直試圖使用memcpy將存儲在sym_table中的符號表條目放入一個名爲bytes_sym的字節整數的數組中,然後將其寫入文件。它複製正確的大小,但由於某種原因而亂放字節的位置。這裏是我的代碼:memcpy混合結構的內容?

/* 
** 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

歡迎來到Stack Overflow。請儘快閱讀[關於]和[問]頁面。數據結構是什麼樣的?我們需要知道這一點。另請閱讀如何創建MCVE([MCVE])。 –

+1

所以你想看看編寫代碼和讀取數據呢?同時使'0x%x'成爲'0x%02x'。 – alk

+2

看起來像一個大的endian vs小端的問題。我們需要更多信息, 特別是[MCVE]會有幫助,但是'memcpy'絕對不會混淆任何東西。問題在別處。 –

回答

-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; 
      } 
    } 
} 
+4

本身,正確使用'memcpy()'不會搞亂任何東西。你沒有提供足夠的信息讓任何人知道你的問題是什麼,您在此答案中未提供足夠的信息來說明您在何處以及如何使用此功能;你對'完全撒謊'的說法是不合理的。你可能有調用未定義行爲的代碼。由於你沒有提供[MCVE],所以很難確定,但是由於編碼不穩定而出現不穩定的行爲。如果使用正確(例如,內存的源區域和目標區域可能不重疊),則可以使用'memcpy()'。 –

+3

Downvoting這個答案,因爲它是誤導。建議'memcpy'能夠識別endian,並以不同的順序向源寫入字節,這顯然是不正確的。你可能遇到的是源數據本身使用與你期望的不同的字節順序。這是一個數據格式問題,與'memcpy'無關。 – paddy

+0

你不應該採取消極的反饋。如果答案包含錯誤信息,那麼它可能會損害未來的讀者,應該指出。 – user694733