我无法弄清楚我的功能有什么问题 - 它会在返回时导致断点。
std::string generateHash(std::string source)
{
CryptoPP::SHA1 hash;
byte digest[CryptoPP::SHA1::DIGESTSIZE];
hash.CalculateDigest(digest, (const byte*)source.c_str(), source.size());
std::string output;
CryptoPP::HexEncoder encoder;
CryptoPP::StringSink test = CryptoPP::StringSink(output);
encoder.Attach((CryptoPP::BufferedTransformation*)&CryptoPP::StringSink(output));
encoder.Put(digest, sizeof(digest));
encoder.MessageEnd();
return output; // here
}
答案 0 :(得分:3)
encoder.Attach((CryptoPP::BufferedTransformation*)&CryptoPP::StringSink(output));
在这一行中,CryptoPP::StringSink(output)
是一个临时对象。此呼叫后CryptoPP::StringSink(output)
不再存在。因此,如果您尝试按照其地址(encoder.Attach
和encoder.Put
),您将获得未定义的行为。 (就像你永远不应该返回局部变量的地址)
我的参考代码:
std::string generateHash(std::string source)
{
CryptoPP::SHA1 hash;
byte digest[CryptoPP::SHA1::DIGESTSIZE];
hash.CalculateDigest(digest, (const byte*)source.c_str(), source.size());
std::string output;
CryptoPP::HexEncoder encoder;
CryptoPP::StringSink test = CryptoPP::StringSink(output);
encoder.Attach(new CryptoPP::StringSink(output));
encoder.Put(digest, sizeof(digest));
encoder.MessageEnd();
return output;
}
答案 1 :(得分:2)
CryptoPP::HexEncoder encoder; CryptoPP::StringSink test = CryptoPP::StringSink(output); encoder.Attach((CryptoPP::BufferedTransformation*)&CryptoPP::StringSink(output));
Onemouth的解决方案是正确的,但这就是你遇到麻烦的原因:
StringSink(output)
在堆栈上是临时的,当StringSink
析构函数运行时它将被清除HexEncoder
'拥有'指向StringSink(output)
的指针,因此HexEncoder
将在StringSink(output)
所以StringSink
被清理了两次。
为了完整性,StringSink
不删除字符串output
,因为它需要引用,而不是指针。
这是README.txt中记录的行为:
88 *** Important Usage Notes ***
89
90 1. If a constructor for A takes a pointer to an object B (except primitive
91 types such as int and char), then A owns B and will delete B at A's
92 destruction. If a constructor for A takes a reference to an object B,
93 then the caller retains ownership of B and should not destroy it until
94 A no longer needs it.
虽然它高度不寻常,但可能能够做你想做的事情并按如下方式修复它(但我不< / em>建议按照你的方式去做):
encoder.Attach(new Redirector(&CryptoPP::StringSink(output)));
Redirector
停止了所有权链。当Redirector
被销毁时,不会破坏其附加的转换(StringSink
)。但同样,它不是使用库的方式。
Redirector
在图书馆的其他地方非常有用,但在这种情况下并非如此。