Chris Chris - 3 months ago 14
C++ Question

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

I'm writing a C++ class to add a digital signature to a PDF, using OpenSSL to generate a SHA1 hash, which I then print to a file:

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();


This code works as expected in Debug mode. In Release mode,
fout << hash
prints 30 instead of SHA_DIGEST_LENGTH = 20 bytes, the last 10 of which look like garbage (maybe buffer overflow?)

My current workaround is to print each character instead of streaming:

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


Which works in both build modes, but I'm curious what could cause the stream operator to misread the length of the string. Does anybody have any thoughts?

For the record, I'm compiling with MSVC++ 12 (x86_amd64).

Answer

There is a stream-inserter for NUL-terminated strings, which is the one selected.

But you are trying to output an array of fixed length containing arbitrary bytes, which is something completely different, leading to UB.

Just use memberfunction write(buffer, size) instead, which is designed for that.

Comments