使用完成端口模型时遇到的坑(学习记录1)
1、完成端口模型的使用中遇到GetQueuedCompletionStatus中的输出参数:“完成键”(lpCompletionKey)返回的地址不能正确指向目标数据。
代码如下:
//INFINITE:无限制等待
if (0 == GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (PULONG_PTR)&PerHandleData, (LPOVERLAPPED *)&PerIoData, INFINITE))
{
cout << "GetQueuedCompletionStatus failed with error " << GetLastError() << endl;
return 0;
}
解决法案:将x64的调试或运行环境改成x86,(原理:64位的环境下的变量的关键字与32位环境的会有差别。具体差别请自行参考资料)64位的环境会导致输出参数的地址截断,从而使得完成键的地址错误。
2、主线程使用了WSARecv后,在子线程中再次调用从而导致了获取异常
小白做法:仅主线程调用WSARecv,子线程负责对数据处理即可。
3、使用过程中因为传参的需要,容易发生数据的存取访问权限冲突。
.error1:内存越界。本人认为越界情况分为两种:一种是指向的地址完全跟目标没有任何关系(即指针error),另一种就是小访大(即指针是对的,但是指针偏移的大小超过了其类型大小)
. error2:内存泄漏,该释放的空间未释放。
. error3:使用的函数有误。比如strcpy和strcpy_s就是这样,看代码:
char szBuf[2] = {0};
strcpy_s(szBuf, 2, "12131"); //新的CRT函数
strcpy(szBuf, "12131"); //老的CRT函数
有明显有缓冲区溢出的问题。 使用strcpy_s函数则会抛出一个异常。而使用strcpy函数的结果则未定,因为它错误地改变了程序中其他部分的内存的数据,可能不会抛出异常但导致程序数据错误,也可能由于非法内存访问抛出异常。