2013-10-24 75 views
0

下面給出的表現是我的示例代碼:的memcpy以意想不到的方式

int function1(unsigned char *out, int length){ 
unsigned long crypto_out_len = 16; 
unsigned char crypto_out[16] = {0}; 
....... 
//produces 16 bytes output & stores in crypto_out 
crypto_function(crypto_out, crypto_out_len); 
//lets say crypto_output contents after are : "abcdefghijklmnop" 
....... 
memcpy(out, crypto_out,length); 
return 0; 
} 

function2(){ 
unsigned char out[10] = {0}; 
function1(out, 10); 
std::pair<unsigned char *,int> map_entry; 
map_entry.first = out; 
map_entry.second = 10; 
} 

現在,map_entry.first應包含以下內容: 「ABCDEFGHIJ」,對不對?

但它包含「abcdefghij#$%f1 ^」,與它關聯的一些垃圾。我應該如何避免這種意外的行爲,以便map_entry.first應該完全包含「abcdefghij」。

回答

1

既然你沒有粘貼整個代碼,我不能100%確定,但我想我知道什麼是錯的。 memcpy()在這裏表現正確,並且所有內容都是100%定義的行爲。

在這種情況下,out是一個10個字符的字符串,而不是的空終止符。您將其指定給unsigned char*,其中不包含長度信息,並且我懷疑您在提及map_entry.first時根本不使用數字10。

如果您將其打印爲unsigned char*或構造std::string,C++希望它是一個以空字符結尾的字符串。因此,它讀取它直到第一個空字符。現在,由於out沒有一個,它只是在out之後開始讀取堆棧中的字符,這正好是您看到的垃圾。

你需要做的是確保或者這個字符串是以null結尾的,或者確保你總是引用它來指定正確的長度。對於前者,你想使out 11字節長,並留下最後一個字節爲0

function2(){ 
    unsigned char out[11] = {0}; 
    function1(out, 10); 
    std::pair<unsigned char *,int> map_entry; 
    map_entry.first = out; 
    map_entry.second = 10; 
} 

也請注意,C++實際上將停止在它遇到的第一個空字符。如果您的crypto_function()可能會在字符串中間輸出零字節,您應該知道該字符串將在該點被截斷。

對於後者,您必須使用實際允許指定字符串長度的函數,並且始終將這些長度傳遞給10。如果你總是這樣工作,你不必擔心crypto_function()的零字節。

+0

但只是爲了確保memcpy從src複製空字符到dest,對不對? – annunarcist

+0

是的。 'memcpy()'拷貝指定的字節數,根本不關心空字符。 'strcpy()'和'strncpy()'停在空字符處。 –

1

您在使用字符串混淆char[]out確實包含您期望的數據,但它不是0終止的,所以如果您嘗試將其顯示爲字符串,它可能看起來像包含額外的數據。如果數據實際上是字符串,則需要正確地終止它們。

相關問題