[英]Read access violation. _Mycont was nullptr error while getting udp data into vectors in C++
[未解决]
我读了此错误文章,我知道在哪种情况下会发生此错误,但是我尝试在代码中找到这种情况,但我一直在努力寻找问题的根源。
总体代码说明:
我从以太网中获取UDP数据包,并通过计算丢失的片段数来分析我的用户创建的标头,以查看是否有丢失的片段(数据包)。 ( lostFragmentCount++
)在执行此操作时,我在while循环中将数据(数据包)连接到数组中。 FrameFragmentNo
和PrevFrameFragmentNo
可以看作是跟踪帧以检测丢失的片段的指针。
有问题的部分是在此行之后concatAry.insert(it+intData.size(),GetIntArrayFromByteArray(vec).begin(), GetIntArrayFromByteArray(vec).end());
在他的那行,我抛出了异常:读取访问冲突。 _Mycont为nullptr。 错误。 当它第三次调用GetIntArrayFromByteArray()
方法时。 (它不会给错误,他的第一名)
我在转换时放置了断点来跟踪那些数组的大小,它看起来是正确的,我怀疑当我们在获取数据的同时从以太网中获取大量数据时,它可能会溢出,但是如果是这种情况,缓冲区应该在进入while之前给出错误。
问题可能源于insert()
方法的使用 。 我想弄清楚。
我不明白为什么要经过一段时间(从以太网获取数据的第n次迭代)后出现此错误。 有人有主意吗?
相关变量
char buf[1550];//message gets here
uint16_t MessageID = 0;
uint16_t MessageLength = 0;
uint32_t FrameCount = 0;
uint16_t TotalFragmentCount = 0;
uint16_t FrameFragmentNo = 0;
uint16_t Reserved = 0;
uint16_t SkipFrameFlag = 1;
uint16_t PrevFrameFragmentNo =0;
uint16_t Ethernet_Packet_Header_Length = 14;
vector<uint16_t> intData;
uint32_t PrevFrameCount = 0;
int ReceivedFrameCount = 0;
int ReceivedFrameLen;
int lostFragmentCount = 0;
uint64_t NumberofFrame = 0;
这是我的while循环,它采用udp数据包剥离(移位)用户创建的标头来保存其余数据:
while (true)
{
ZeroMemory(&client, clientLength); // Clear the client structure
ZeroMemory(buf, 1550); // Clear the receive buffer
// Wait for message
int bytesIn = recvfrom(in, buf, 1550, 0, (sockaddr*)&client, &clientLength);
if (bytesIn == SOCKET_ERROR)
{
cout << "Error receiving from client " << WSAGetLastError() << endl;
continue;
}
//parse the user created header for further use
MessageID = (uint16_t)(buf[0] << 8 | buf[1]);
FrameCount = (uint32_t)(buf[2] << 24 | buf[3] << 16 | buf[4] << 8 | buf[5] << 0);
TotalFragmentCount = (uint16_t)(buf[6] << 8 | buf[7]);
FrameFragmentNo = (uint16_t)(buf[8] << 8 | buf[9]);
Reserved = (uint16_t)(buf[10] << 8 | buf[11]);
MessageLength = (uint16_t)(buf[12] << 8 | buf[13]);
if (FrameFragmentNo == 1 && SkipFrameFlag == 1) // After the skip flag, catch the start of frame.
{
SkipFrameFlag = 0;
PrevFrameFragmentNo = 0;
//Array.Clear(intData, 0, intData.Length);
}
if (FrameFragmentNo != (PrevFrameFragmentNo + 1)) //Fragment is lost. Skip Frame
{
SkipFrameFlag = 1;
lostFragmentCount++;
}
if (SkipFrameFlag == 1)
continue;
//skip user created header
int shift = 14;
int length = sizeof(buf);
memmove(buf, buf + shift, length - shift);
memset(buf + length - shift, '0', shift);
//char buf ----> vecor<char> vec
int n = sizeof(buf) / sizeof(*buf);//number of elements
vector<char> vec(buf, buf + n);
if (FrameFragmentNo == 1)// First fragment
{
intData = GetIntArrayFromCharArray(vec);
PrevFrameFragmentNo = FrameFragmentNo;
}
else if (FrameFragmentNo <= TotalFragmentCount) // Other Fragments
{
std::vector<uint16_t>::iterator it;
vector<uint16_t> concatAry;
it = concatAry.begin();
concatAry.insert(concatAry.begin(), intData.begin(), intData.end());
concatAry.insert(it + intData.size(),GetIntArrayFromCharArray(vec).begin(), GetIntArrayFromCharArray(vec).end());
intData = concatAry;
PrevFrameFragmentNo = FrameFragmentNo;
count++;
}
if (FrameFragmentNo == TotalFragmentCount && intData.size() != 0) // Frame Fragmentation Completed
{
PrevFrameFragmentNo = 0;
PrevFrameCount = FrameCount;
ReceivedFrameCount++;
ReceivedFrameLen = intData.size();
//apply till here
NumberofFrame++;
}
//Write data into a file
filePutContents("C:\\Users\\Dell\\UDPClientServerBasic\\UDP_Server\\UDP_Server\\recordings.txt", intData, true);
}//end of while
这是GetIntArrayFromCharArray()方法
vector<uint16_t> GetIntArrayFromCharArray(vector<char> arr)
{
// If the number of bytes is not even, put a zero at the end
if ((arr.size() % 2) == 1)
arr.resize(arr.size()+1);
//arr.push_back(0);
vector<uint16_t> intArray;
for (int i = 0; i < arr.size(); i += 2)
intArray.push_back((uint16_t)((arr[i] << 8) | arr[i + 1]));
/*arr[i + 1] gives warning saying "Arithmetic overflow: Using operator '+' on a 4 byte value
and then casting the result to a 8 byte value."
But I don't think this could be a issue since it is just for loop's iterator
*/
return intArray;
}
[EDIT]更清晰地查看错误
迭代器it = concatAry.begin();
第一次插入后无效。 在第二个插入中使用concatAry.begin()
代替it
:
concatAry.insert(concatAry.begin()+intData.size(),GetIntArrayFromCharArray(vec).begin(), , GetIntArrayFromCharArray(vec).end());
似乎在假定std::copy
时使用了insert
。 在insert
之前使用std::copy
或删除大小构造函数(使用vector<uint16_t> concatAry;
不带size参数)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.