Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用vector<;char>;作为字符数组上的输入缓冲区?_C++_Networking - Fatal编程技术网

C++ 使用vector<;char>;作为字符数组上的输入缓冲区?

C++ 使用vector<;char>;作为字符数组上的输入缓冲区?,c++,networking,C++,Networking,我正在做一个网络编程,我看到有人使用vector作为socket的输入缓冲区,而不是char数组 我想知道这样做有什么好处 提前感谢..矢量可以轻松调整大小并允许方便地部分删除数据-这是一大优势。在许多情况下,使用固定大小的数组是不方便的——例如,您将读取数据块,并以比接收到的数据块小的数据块处理接收到的数据。然后您想知道剩下的实际数据量-即vector.size(),您不必将其存储在单独的变量中,当您删除部分数据时vector将为您移动剩余的数据。使用vector是: 容易成长的记忆空间 易

我正在做一个网络编程,我看到有人使用vector作为socket的输入缓冲区,而不是char数组

我想知道这样做有什么好处


提前感谢..

矢量
可以轻松调整大小并允许方便地部分删除数据-这是一大优势。在许多情况下,使用固定大小的数组是不方便的——例如,您将读取数据块,并以比接收到的数据块小的数据块处理接收到的数据。然后您想知道剩下的实际数据量-即
vector.size()
,您不必将其存储在单独的变量中,当您删除部分数据时
vector
将为您移动剩余的数据。

使用vector是:

  • 容易成长的记忆空间
  • 易于复制数据
  • 很容易免费
向量本质上只是一个托管字符数组

所以你可以写:

{
    vector<char> buf(4096);
    ...
    int result = recv(fd, &buf[received_so_far], buf.size() - received_so_far);
    ...
}
{
载体buf(4096);
...
int result=recv(fd,&buf[received\u sou\u far],buf.size()-received\u sou\u far);
...
}
向量“知道”它的大小,因此您可以在任何地方使用
buf.size()
,而不必担心缓冲区溢出。您还可以更改声明中的大小,使其在任何地方都生效,而无需任何混乱的定义

使用
buf
将在堆上分配底层数组,当
buf
超出范围时,无论发生什么情况(例如异常或提前返回),它都会自动释放它。因此,您可以在保持堆上的大型对象的同时获得堆栈分配的良好语义

您可以使用
buf.swap()
非常有效地将底层字符数组的所有权“移交”给另一个
vector
。(这对于网络流量来说是个好主意……现代网络速度很快。你最不想做的事情就是为从网络接收到的每个字节创建另一个副本。)而且你仍然不必担心显式释放内存

对于这个特殊的应用程序,这些都是我脑海中浮现出来的巨大优势。

我的主要原因:

  • 它的例外是安全的。
    • 无论发生什么错误,向量都不会泄漏内存

如果您曾经用Java编写过网络应用程序,那么您很可能熟悉和熟悉Java。这两个类通过非常简单直观的界面使缓冲区处理变得非常简单

在C++世界中,很幸运的是,用标准的向量类,这两个类所提供的一切都是你可以使用的。由于vector可以动态增长,它甚至比ByteBuffer和IoBuffer更强大。只要编写代码,就可以在字节缓冲区包装器中找到所需的一切

一些明显的优势:

  • 使用vector::reserve预分配内存
  • 使用vector::size记住缓冲区位置
  • 使用vector::resize增长/清除缓冲区
  • 使用_向量[0]转换为C缓冲区(&U)
  • 使用vector::swap传输缓冲区所有权
  • 。。。还有更多有待发现

std::vector buffer(SIZE)和
std::array buffer
之间的一个主要区别是
SIZE
参数的位置:对于
vector
,您只需要在运行时知道大小,如果需要,甚至可以更改大小。对于
array
SIZE
是一个模板参数,因此您需要在编译时就知道它,并且在重新编译之前它保持不变。因此,基本上,
std::array
只是C风格数组
char buffer[SIZE]
的包装器。虽然C++ 14标准中,C样式数组可以在C++中动态地被调整,<>代码>:ST::数组< /COD>总是静态大小。但是,请注意,C样式的数组通常是在堆栈上分配的,并且在大多数实现中,堆栈空间是有限的

下一个区别是,
std::vector
对其元素执行值初始化,这通常意味着将它们设置为零(除非使用自定义构造函数重写),而
std::array
和C样式数组使其内容未初始化

因此:

  • 如果您需要一个已知固定大小的缓冲区,如果该大小不超过几千字节,并且应用程序将正确写入该缓冲区的内容,请使用
    std::array
    或C样式的数组。这是更快的解决方案
  • 否则,请使用
    std::vector
    。这是更安全的解决方案

size()
恒定时间吗?如果是这样的话,这对裸字符数组(以null结尾)也有好处。@Merlyn Morgan Graham:您经常操作一开始就不是以null结尾的数据。“删除部分数据”实际上是一个可怕的想法。它确实能工作,但效率极低。@Nemo:这不是最有效的操作,但如果你删除一个相当小的向量的很大一部分,这不是一个大问题。但它确实会生成至少部分数据的另一个副本。我同意这取决于你的申请。但是,如果您在现代网络上推送任何数量不平凡的数据,您真的不能对内存中的数据移动如此懒惰。。。我没有投你反对票,因为你没有错。但我确实认为,除了“玩具”应用之外,你给的建议太差了。谢谢你善意的回答。我复制向量copyVector的方式(m_vbuffer);我应该交换而不是复制吗?交换比复制有什么好处?在这种情况下,交换没有多少好处。如果一个向量没有默认初始化它的内容,那么这将是一个好处。但确实如此,将零写入内存所需的时间与复制到另一个向量所需的时间相同。@Zan