用C ++ / STL存储二进制数据的“正确”方法
一般来说,在C ++中存储二进制数据的最好方法是什么? 就我所知,这些选项几乎可以归结为使用string或向量<char>。 (我会省略char * s和malloc()的可能性,因为我特指C ++)。
通常我只是使用一个string,但是我不确定是否有我缺less的开销,或者STL在内部执行的转换可能会混淆二进制数据的完整性。 有没有人有任何指针(har)呢? build议或喜好这样或那样?
char的向量很好,因为内存是连续的。 因此,您可以将其与许多C API(如berkley套接字或文件API)一起使用。 您可以执行以下操作,例如:
std::vector<char> vect; ... send(sock, &vect[0], vect.size());
它会正常工作。
你可以像对待任何其他dynamic分配的字符缓冲区一样对待它。 你可以上下扫描寻找神奇的数字或模式。 你可以部分parsing它。 对于从套接字接收,你可以很容易地调整它来附加更多的数据。
缺点是resize不是非常有效(谨慎resize或预先分配),从arrays的前面删除也是非常不够的。 如果你需要比较频繁地在数据结构的前面一次性地popup一个或两个字符,在这个处理之前复制到一个deque可能是一个选项。 这花费你一个副本和deque内存不连续,所以你不能只传递一个指针到C API。
底线,深入了解数据结构和他们之间的权衡,然而,char的向量通常是我在一般实践中看到的。
std :: string的最大问题是当前的标准不能保证它的底层存储是连续的。 但是,没有已知的STL实现,其中string不是连续的,所以实际上它可能不会失败。 事实上,新的C ++ 0x标准将要解决这个问题,强制std :: string使用一个连续的缓冲区,比如std :: vector。
反对string的另一个说法是,它的名字暗示它包含一个string,而不是一个二进制缓冲区,这可能会导致读取代码的人感到困惑。
也就是说,我也推荐vector。
我也使用std::string
,从来没有问题。
一个“指针”,我刚刚在一段代码中得到了一个清晰的提示:当从一个二进制数据块创build一个string时,使用std::string(startIter, endIter)
构造函数forms,而不是std::string(ptr, offset, length)
forms – 后者假设指针指向一个C风格的string,在第一个零字符之后忽略任何东西(它复制到指定的length
,而不是length
字符) 。
你当然应该使用一些char的容器,但是你要使用的容器取决于你的应用程序。
字符有几个属性,使他们有用的保存二进制数据:标准不允许任何“填充”字符数据types,这是非常重要的,因为这意味着你不会在你的二进制布局中得到垃圾。 每个字符也保证只有一个字节,使其成为唯一的具有设置宽度的普通旧数据types(POD)(所有字符都是以上限和/或下限来指定的)。
讨论合适的stl容器来存储字符在上面的Doug处理得很好。 你需要哪一个完全取决于你的用例。 如果你只是持有一个数据块,没有任何特殊的查找,追加/删除或拼接的需要,我更喜欢vector,这使得你的意图比std :: string更清晰,许多库和函数将会承担保存一个以null结尾的c风格的string。