memcpy以一种意想不到的方式表现

时间:2013-10-24 04:05:27

标签: c++ c pointers out-of-memory 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”。

2 个答案:

答案 0 :(得分:1)

您将char[]与字符串混淆。 out确实包含您的预期数据,但它不会终止,因此如果您尝试将其显示为字符串,则可能看起来包含额外数据。如果数据实际上是字符串,则需要正确地终止它们。

答案 1 :(得分:1)

由于你还没有粘贴整个代码,我不能100%肯定,但我想我知道什么是错的。 memcpy()在这里表现正常,一切都是100%定义的行为。

在这种情况下,out是一个10个字符的字符串,没有一个空终止符。您将其分配给不包含长度信息的unsigned char*,并且我怀疑您在引用map_entry.first时根本不使用数字10。

如果您将其打印为unsigned char*或使用它构造std::string,则C ++希望它是以空字符结尾的字符串。因此,它会读取它直到第一个空字符。现在,由于out没有一个,它只是在out之后运行并开始读取堆栈中的字符,这恰好是你所看到的垃圾。

您需要做的是确保 字符串以空值终止,或确保始终引用它指定正确的长度。对于前者,您需要将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()的零字节。