以下是我的示例代码:
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”。
答案 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()
的零字节。