2014-12-21 77 views
3

下面是一個簡單的測試程序,它說明了我所面臨的問題:錯誤地使用std :: copy?

#include <iostream> 
#include <stdlib.h> 
#include <inttypes.h> 
#include <vector> 

using namespace std; 
typedef unsigned char Byte; 

int main() 
{ 
    uint32_t ui32 = 12; 
    size_t sizeofUi32 = sizeof ui32; 
    cout << "sizeofUi32: " << sizeofUi32 << endl; 
    vector<Byte> v(10); 
    std::copy(&ui32, &ui32 + sizeof ui32, &v[4]); 

    uint32_t result = 0; 
    std::copy(&v[4], &v[4] + sizeof ui32, &result); 

    cout << "Result: " << result << " sizeofUi32: " << sizeofUi32 << endl; 

    return 0; 
} 

輸出:

sizeofUi32: 4  
Result: 12 sizeofUi32: 17179869184 

我想這個問題可能是由於到std ::複製接受迭代器不是指針,而是從我在SO here了,

的指針是一個迭代

所以我的示例代碼必須有一個簡單的問題,我錯過了。但我無法發現它。 你能解釋一下,這裏有什麼問題嗎?

編輯1:

從我上心的答案,即反序列化的字節向量,如果我知道正確的順序和類型在矢量存儲的數據的,我能避免使用std

所以: :複製並將矢量值分配給適當類型的變量。它有效,但安全嗎?

uint32_t a = v[4]; 
uint8_t b = v[8]; 
+1

您可能想使用'std :: copy_n' –

+0

@AlexandreC。,對!感謝您的提示 – rightaway717

回答

8

眼前的問題是在這裏:

std::copy(&ui32, &ui32 + sizeof ui32, &v[4]); 
         ^^^^^^^^^^^^^ 

&ui32的類型爲uint32_t *,並添加任何東西已經考慮到對象的大小。您有效嘗試複製sizeof ui32uint32_t對象,但您只有一個對象,因此您應該使用+ 1

另外,使用std::copy指針不同類型可能不會給你你期望的結果。它的效果是v[4] = ui32;,只要ui32位於Byte的範圍內,它就在這裏,但這通常不是你可以依賴的。

第二個std::copy有大致相同的問題,但方向相反。

你可以做的是:

std::copy((Byte*) &ui32, (Byte*) (&ui32 + 1), &v[4]); 
// or std::copy((Byte*) &ui32, (Byte*) &ui32 + sizeof ui32, &v[4]); 
... 
std::copy(&v[4], &v[4] + sizeof ui32, (Byte*) &result); 
+0

因此,從我的答案中,我需要將'std :: copy'中使用的指針轉換爲相同類型以實現所需的結果,對吧? – rightaway717

+0

@ rightaway717不只是相同的類型,特別是'Byte *'('unsigned char *')。如果嘗試轉換其他方法,如果嘗試對所有三個參數使用'uint32_t *',則可能會發現'&v [4]'不適合對齊。 – hvd

3

的問題是不是與std::copy但指針運算。正如你所說的,「指針是一個迭代器」。但更重要的是,這是強類型。因此,指向uint32_t的指針與指向unsigned char的指針不同。

添加&ui32 + sizeof ui32有效地將ui32看作好像它是具有4個元素(類型uint32_t)的連續數組的開始。