write方法修改输入参数

ostringstream::write method modifies input parameter

本文关键字:参数 输入 修改 方法 write      更新时间:2023-10-16

考虑下面的代码片段,它获取一些二进制数据并将其写入ostringstream对象:

unsigned char* payload;
unsigned long  size;
GetData(&payload, &size);
std::cout << md5(payload, size) << std::endl;
std::ostringstream stream;
stream.write((const char*)payload, size);
std::cout << md5(payload, size) << std::endl;

问题是,两个打印的哈希值彼此不同,这意味着payload已经改变了。我试着用std::ostringstream stream(std::ios::out | std::ios::binary)在二进制模式下打开stream,它没有什么不同,我没有预料到它会,无论如何。

另一个事实是,每次重新运行程序时,我都会从第二个print语句获得不同的校验和。第一个哈希值总是相同的

现在,我如何将二进制数据正确地写入ostringstream?问题是否可以转换为const char* (GetData方法将unsigned char**作为第一个参数)?

更新:根据评论,这里有一些更多的解释:

  • 比较原始数据和写入数据的二进制差异,我看到写入数据在某些地方向右移动(24字节)。它还在最开始添加了一些字节。我还是觉得这和演员阵容有关。
  • GetData和实际写入之间没有更多的代码。
  • GetData工作正确,因为调用后的校验和是正确的(我知道校验和应该是什么)。
  • 我不能发布可编译的代码,因为GetData。这是没有必要的,我已经将问题隔离到调用write的行。
  • 系统详细信息为:gcc版本4.6.3在Ubuntu 12.04 64位

问题的奥秘原来在于数据的大小。

在实验了不同的大小值后,发现ostringstream的内部缓冲区大约是65KB,确切地说是65504字节。当大小较大时,会出现奇怪的移位和残缺的字节。

解决方法是使用:
stream.rdbuf()->pubsetbuf((const char*)payload, payloadSize)

代替write方法。但是当这个作用域终止时,有效载荷将失效,stream不能再在其他任何地方使用。在我的例子中,它需要在其他地方使用。

这表明:

  • 我确实是对的,问题是与ostringstream,但不是与哈希或其他任何东西。
  • STL的字符串流显然有默认的缓冲区大小限制。这是将来要记住的。