我有下面的代码my_test_function().
在my_test_function()我调用encrypt_rsa()它返回一个字符串。在内部,encrypt_rsa() 根据以下代码调用 convert_cryptopp_integer(..):
std::vector<byte> v = convert_cryptopp_integer(c);
string res(v.begin(), v.end());
return res;
发生的事情是我在 my_test_function() 中用 cout "chars are" 打印出字符串 encmsg。
稍后在代码中,我再次使用 "chars are" 打印出相同的字符串。没有做任何改变,但有时打印出完全相同的字符串数据是不同的。
行为似乎与时间有关。例如,代码正在运行,我添加了一些打印输出,但它坏了。
我认为正在发生的事情是 CryptoPP 正在更改此字符串内存,因为这是最初分配字符串的内容,我将其传回。分配它的函数是:convert_cryptopp_integer(..)
就好像内存管理试图恢复 RAM,所以当我到达代码底部时,底层内存已经改变。但是,如果内存消失了,我应该会收到内存访问错误或段错误?
我还通过声明另一个向量来尝试在 convert_cryptopp_integer(..) 中对向量进行深度复制:
std::vector<byte> v;
std::vector<byte> v2;
..
v2 = v;
return v2
这没用。
std::vector<byte> convert_cryptopp_integer(Integer n){
const size_t len = n.MinEncodedSize(Integer::UNSIGNED);
std::vector<byte> v;
v.resize(len);
n.Encode((byte*)&v[0], v.size(), Integer::UNSIGNED);
return v;
}
void my_test_function(string country_code, int sock, CryptoPP::RSA::PublicKey MASTER_PUB_KEY, int i, string server_address, unsigned short server_port, string message, bool encrypt){
//placeholder
try{
const char* msg;
size_t msg_len = 0;
if(encrypt){
cout << " Encryption RSA message " << message << endl;
string encmsg = encrypt_rsa(message, MASTER_PUB_KEY);
cout << " The encmsg is " << encmsg << " length is " << encmsg.length() << endl;
msg = encmsg.c_str();
msg_len = encmsg.length();
**cout << " chars are " << *msg << " and " << *(msg+1) << " ending in " << *(msg+msg_len-1) << endl;**
}else{
msg = message.c_str();
msg_len = message.length();
}
//setup the endpoint
struct sockaddr_in server_addr;
socklen_t len = sizeof(server_addr);
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(server_address.c_str());
server_addr.sin_port = htons(server_port);
fd_set set;
struct timeval timeout;
int rv;
FD_ZERO(&set); /* clear the set */
FD_SET(sock, &set); /* add our file descriptor to the set */
timeout.tv_sec = std_thread_timeout_microseconds/1000000;
timeout.tv_usec = 0;
//when the socket is ready for writing
rv = select(sock + 1, NULL, &set, NULL, &timeout);
if (rv == -1)
{
//perror("select"); /* an error occurred */
//return 1;
}
else if (rv == 0)
{
//printf("timeout occurred\n"); /* a timeout occurred */
//return 1;
cout << " Client not ready " << endl;
}
else
{
cout << " Ready to write " << endl;
**cout << " chars are " << *msg << " and " << *(msg+1) << " ending in " << *(msg+msg_len-1) << endl;**
sendto(sock , msg, msg_len, 0, (struct sockaddr *) &server_addr, sizeof(server_addr) );
}
}catch(Exception e){
cout << " Exception in send broker message " << e.what() << endl;
return;
}
}
一个错误是这样的:
if(encrypt)
{
cout << " Encryption RSA message " << message << endl;
string encmsg = encrypt_rsa(message, MASTER_PUB_KEY);
cout << " The encmsg is " << encmsg << " length is " << encmsg.length() << endl;
msg = encmsg.c_str();
msg_len = encmsg.length();
cout << " chars are " << *msg << " and " << *(msg+1) << " ending in " << *(msg+msg_len-1) << endl;
}else{
msg = message.c_str();
msg_len = message.length();
}
encmsg
是局部变量,因此 msg
将保存缓冲区的地址,一旦 encmsg
超出范围,该地址将无效。
然后您稍后在这里使用
msg
:
sendto(sock , msg, msg_len, 0, (struct sockaddr *) &server_addr, sizeof(server_addr) );
谁知道
msg
包含什么,因为 encmsg
已经超出范围。