我有一个带有std::vector<unsigned char> mPacket作为数据包缓冲区的类(用于发送UDP字符串)。有一个对应的成员变量mPacketNumber跟踪到目前为止已发送了多少个数据包。

我在课堂上做的第一件事是保留空间:

mPacket.reserve(400);


然后,在我希望发送数据包时运行的循环中:

mPacket.clear(); //empty out the vector
long packetLength = 0; //keep track of packetLength for sending udp strings

memcpy(&mPacket[0], &&mPacketNumber, 4); //4 bytes because it's a long
packetLength += 4; //add 4 bytes to the packet length

memcpy(&mPacket[packetLength], &data, dataLength);
packetLength += dataLength;

udp.send(mPacket.data(), packetLength);


除非我意识到什么都没发!多么奇特。

因此,我进行了更深入的研究,发现mPacket.size()返回零,而packetLength返回我认为数据包应该是的大小。

我想不出mPacket具有零长度的原因-即使我对数据进行了错误处理,带有mPacketNumber的标头也应该写得很好。

谁能说出我为什么遇到这个问题?

谢谢!

最佳答案

您保留的元素不能正常使用。仅当您调整矢量大小时,才会创建元素。尽管它看起来可以以某种方式起作用,但是对于具有构造函数的类型,情况会有所不同-您会看到未调用构造函数。这是未定义的行为-在这种情况下,您正在访问不允许的元素。

.reserve()操作通常与.push_back()一起使用,以避免重新分配,但是这里不是这种情况。

如果使用.size(),则不会修改.reserve()。您应该改为使用.resize()



或者,您可以将复制操作与.push_back().reserve()一起使用,但是您需要删除memcpy的用法,而是将std::copystd::back_inserter一起使用,而.push_back()使用reinterpret_cast进行推送另一个容器的元素:

std::copy(reinterpret_cast<unsigned char*>(&mPacketNumber), reinterpret_cast<unsigned char*>(&mPacketNumber) + sizeof(mPacketNumber), std::back_inserter(mPacket))
std::copy(reinterpret_cast<unsigned char*>(&data), reinterpret_cast<unsigned char*>(&data) + dataLength, std::back_inserter(mPacket));


这些令人讨厌,但是代码仍然具有一个优势-如果您的估计值太低,您将不会缓冲区溢出。

关于c++ - memcpy不复制到缓冲区,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27772498/

10-12 22:47