std::ofstream 在给定一个无符号字符数组时打印额外的字节,但仅在发布模式下

std::ofstream prints extra bytes when given an array of unsigned char, but only in Release mode

我正在编写 C++ class 以将数字签名添加到 PDF,使用 OpenSSL 生成 SHA1 哈希,然后将其打印到文件中:

unsigned char hash[SHA_DIGEST_LENGTH];
SHA1((unsigned char *)temp.c_str(), temp.size(), hash);

std::ofstream fout("resources/hash.out", std::ios::binary);
fout << hash;
fout.close();

此代码在调试模式下按预期工作。在 Release 模式下,fout << hash 打印 30 而不是 SHA_DIGEST_LENGTH = 20 个字节,最后 10 个看起来像垃圾(可能是缓冲区溢出?)

我目前的解决方法是打印每个字符而不是流式传输:

for (int i=0; i<SHA_DIGEST_LENGTH; ++i)
    fout.put(hash[i]);  

这在两种构建模式下都有效,但我很好奇什么会导致流运算符误读字符串的长度。有人有什么想法吗?

郑重声明,我正在使用 MSVC++ 12 (x86_amd64) 进行编译。

有一个用于以 NUL 结尾的字符串的流插入器,这是所选的那个。

但是你试图输出一个包含任意字节的定长数组,这是完全不同的东西,导致UB。

只需使用专门为此设计的成员函数 write(buffer, size)

您需要考虑到 OpenSSL 的 SHA 方法不会以 null 终止输出。普通的operator <<需要空终止,所以不能直接使用。

要使用 C++ 流打印此 "unterminated" 字符串,请参阅

C++ non null terminated char array outputting

对于printf例如

Using printf with a non-null terminated string