我有一个带有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::copy
与std::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/