我不完全是 C++ 新手,但过去我很少认真对待它,所以我对其设施的了解相当粗略。
我正在用 C++ 编写一个快速的概念验证程序,我需要一个动态大小的二进制数据缓冲区。也就是说,我要从网络套接字接收数据,但我不知道会有多少(虽然不超过几 MB)。我可以自己编写这样的缓冲区,但是如果标准库可能已经有了一些东西,为什么还要麻烦呢?我使用的是 VS2008,所以一些微软特定的扩展对我来说很好。我只需要四个操作:
- 创建缓冲区
- 将数据写入缓冲区(二进制垃圾,不以零结尾)
- 将写入的数据获取为 char 数组(连同其长度)
- 释放缓冲区
类/功能集/我需要的任何名称是什么?
添加:std::vector
获得了几票。一切都很好,但我不想逐字节推送几 MB 的数据。套接字将以几 KB 的大块向我提供数据,所以我想一次将它们全部写入。此外,最后我需要将数据作为简单的 char* 获取,因为我需要将整个 blob 传递给未修改的一些 Win32 API 函数。
最佳答案
你想要一个 std::vector
:
std::vector<char> myData;
vector
会自动为你分配和释放它的内存。使用 push_back
添加新数据(vector
将根据需要为您调整大小),并使用索引运算符 []
检索数据。
如果您在任何时候都可以猜出您需要多少内存,我建议调用 reserve
以便后续 push_back
不必重新分配那么多.
如果你想读入一 block 内存并将其附加到你的缓冲区,最简单的可能是这样的:
std::vector<char> myData;
for (;;) {
const int BufferSize = 1024;
char rawBuffer[BufferSize];
const unsigned bytesRead = get_network_data(rawBuffer, sizeof(rawBuffer));
if (bytesRead <= 0) {
break;
}
myData.insert(myData.end(), rawBuffer, rawBuffer + bytesRead);
}
myData
现在拥有所有读取的数据,逐 block 读取。但是,我们复制了两次。
我们改为尝试这样的事情:
std::vector<char> myData;
for (;;) {
const int BufferSize = 1024;
const size_t oldSize = myData.size();
myData.resize(myData.size() + BufferSize);
const unsigned bytesRead = get_network_data(&myData[oldSize], BufferSize);
myData.resize(oldSize + bytesRead);
if (bytesRead == 0) {
break;
}
}
直接读入缓冲区,代价是偶尔会过度分配。
这可以通过例如将每个调整大小的 vector 大小加倍以摊销调整大小,正如第一个解决方案隐式所做的那样。当然,如果您对最终缓冲区的可能大小有先验知识,则可以预先 reserve()
一个更大的缓冲区,以最小化调整大小。
两者都留给读者作为练习。 :)
最后,如果您需要将数据视为原始数组:
some_c_function(myData.data(), myData.size());
std::vector
保证是连续的。
关于c++ - C++中的动态缓冲区类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1874354/