0

下面是我的示例代码:

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”。

4

2 回答 2

1

char[]对字符串感到困惑。out确实包含您预期的数据,但它不是以 0 结尾的,因此如果您尝试将其显示为字符串,它可能看起来包含额外的数据。如果数据实际上是字符串,则需要正确 0 终止它们。

于 2013-10-24T04:12:05.660 回答
1

由于您尚未粘贴整个代码,因此我不能 100% 确定,但我想我知道出了什么问题。memcpy()在这里行为正确,一切都是 100% 定义的行为。

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

如果将它打印为unsigned char*std::string用它构造 a,C++ 期望它是一个以空值结尾的字符串。因此,它会一直读取到第一个空字符。现在,由于out没有它,它只是跑过去并开始读取堆栈上的字符,之后out恰好是您认为是垃圾的内容。

您需要做的是确保字符串以空字符结尾,或者确保始终引用它并指定正确的长度。对于前者,您需要out11 字节长,并将最后一个字节保留为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().

于 2013-10-24T04:17:23.637 回答