将read()直接用于C ++ std:vector
我在一些嵌入式系统的C ++中封装了用户空间linux套接字功能(是的,这可能是再次重新发明轮子)。
我想提供一个使用矢量的读写实现。
做写操作非常简单,我只需传递&myvec[0]
并避免不必要的复制。 我想要做同样的事情,并直接读入一个向量,而不是读入char缓冲区,然后将所有这些拷贝到一个新创建的向量中。
现在,我知道要读取多少数据,并且可以正确分配( vec.reserve()
)。 我也可以读入&myvec[0]
,尽管这可能是一个非常糟糕的想法。 显然,这样做不允许myvec.size返回任何明智的内容。 有没有办法做到这一点:
char *
样式缓冲区到C ++向量。 使用resize()
而不是reserve()
。 这将正确设置向量的大小 - 之后, &myvec[0]
像往常一样保证指向一个连续的内存块。
编辑:使用&myvec[0]
作为指向底层数组的读写指针是安全的,并且可以保证按照C ++标准工作。 以下是Herb Sutter所说的话:
那么为什么人们不断地问std :: vector(或std :: array)的元素是否连续存储? 最可能的原因是他们想知道他们是否可以用指向内部的指针来共享数据,或者读取或写入与C数组中的其他代码共享的数据。 这是一个有效的用途,并且是一个足以保证在标准中足够重要的用途。
假设它是一个POD结构,调用resize
而不是reserve
。 你可以定义一个空的默认构造函数,如果你真的不想在填充矢量之前将数据清零。
它的水平有点低,但是POD结构的构建语义是故意的。 如果允许memmove
复制构建它们,我不明白为什么socket读取不应该。
编辑:啊,字节,不是一个结构。 那么,你可以使用相同的技巧,并定义一个结构只有一个char
和一个忽略初始化它的默认构造函数...如果我正确地猜测你关心,这就是为什么你想调用reserve
而不是resize
在第一名。
如果你想要向量反映读取的数据量,调用resize()
两次。 一次在阅读前,给自己空间阅读。 在读取之后再次将vector的大小设置为实际读取的字节数。 reserve()
并不好,因为调用预留并不允许您访问为容量分配的内存。
第一个resize()
将零矢量的元素归零,但这不太可能造成很大的性能开销。 如果确实如此,您可以尝试Potatoswatter的建议,或者您可以放弃反映读取数据大小的向量大小,而只resize()
一次,然后重新使用它,就像您分配的缓冲区一样在C.
从性能角度看,如果您是在用户模式下从套接字读取数据,则很可能您可以像处理数据一样快速地处理数据。如果您要连接到另一台千兆位局域网上的计算机,或者如果您的计算机是频繁运行100%CPU或100%内存带宽。 无论如何,如果你最终会阻止read
调用,那么额外的复制或memsetting是没有什么大不了的。
和你一样,我想避免用户空间中的额外副本,但不是出于性能原因,仅仅因为如果我不这样做,我不必为它编写代码...
链接地址: http://www.djcxy.com/p/91697.html