C++ dll 内存泄露问题

RoadRoadRuner 2018-01-20 04:42:01
各位大侠:
现今遇到一个问题,我在线程中动态调用了DLL,发现系统的句柄数不断升高,最后确定为其中一个方法,这个方法的目的是连接一个USB设备,只要一运行该方法,就会导致系统句柄数升高,最后死锁。我认为应该内存泄露问题,但苦于找不到泄漏的地方,现把代码贴出来,求助!
// 1 返回成功
// 0 无法创建设备句柄
//
int UsbConnect(int m_PID,int m_VID)
{

//获得所有的HIDS
HidD_GetHidGuid(&HidGuid);

//获得指向的句柄
hDevInfo=SetupDiGetClassDevs(&HidGuid,NULL,NULL,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);

//获得明细数据大小
devInfoData.cbSize = sizeof(devInfoData);

//开始查找设备
bool LastDevice = FALSE; //是否最后一个
int MemberIndex = 0; //成员序号
bool MyDeviceDetected; //是否找到

LastDevice = FALSE;
MemberIndex = 0;
detailData = NULL;
DeviceHandle=NULL;
LONG Result;

do
{
//枚举每个设备
Result=SetupDiEnumDeviceInterfaces(hDevInfo,0,&HidGuid,MemberIndex,&devInfoData);

if(Result !=0)
{
//每个设备的明细数据
Result = SetupDiGetDeviceInterfaceDetail(hDevInfo,&devInfoData,NULL,0,&Length,NULL);

//获得明细数据大小

detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);

//设置数据大小

detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

//再次调用,获得实际明细数据

Result = SetupDiGetDeviceInterfaceDetail(hDevInfo,&devInfoData,detailData,Length,&Required,NULL);

//获得具体对象句柄
DeviceHandle=CreateFile(detailData->DevicePath,0,FILE_SHARE_READ|FILE_SHARE_WRITE,(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,0,NULL);

if(DeviceHandle != INVALID_HANDLE_VALUE)
{
//获得参数
Attributes.Size = sizeof(Attributes);
Result = HidD_GetAttributes(DeviceHandle,&Attributes);

MyDeviceDetected = FALSE;

if (Attributes.VendorID == m_VID)
{
if (Attributes.ProductID == m_PID)
{
MyDeviceDetected = TRUE;

//设定写句柄
WriteHandle=CreateFile(detailData->DevicePath,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING,0, NULL);

//设定读句柄
ReadHandle=CreateFile(detailData->DevicePath,GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);

//获得读写容量
PHIDP_PREPARSED_DATA PreparsedData;
HidD_GetPreparsedData(DeviceHandle,&PreparsedData);
HidP_GetCaps (PreparsedData,&Capabilities);
HidD_FreePreparsedData(PreparsedData);

//事件处理
EventInit();

break; //跳出循环
} //PID
else
{
//PID不匹配
CloseHandle(DeviceHandle);
//CloseHandle(WriteHandle);
// CloseHandle(ReadHandle);
}
} //VID
else
{
//CloseHandle(hDevInfo);
CloseHandle(DeviceHandle);
//CloseHandle(WriteHandle);
//CloseHandle(ReadHandle);
}
}
else
{
//无法创建
//CloseHandle(hDevInfo);
CloseHandle(DeviceHandle);
//CloseHandle(WriteHandle);
//CloseHandle(ReadHandle);
}
}
else
{
// CloseHandle(hDevInfo);
//CloseHandle(DeviceHandle);
LastDevice=true;
}

//CloseHandle(DeviceHandle);
//CloseHandle(WriteHandle);
//CloseHandle(ReadHandle);

MemberIndex += 1;

free(detailData);
detailData = NULL;
DeviceHandle=NULL;

}while((LastDevice == false) && (MyDeviceDetected == false));


if(MyDeviceDetected == true)
return 1; //成功
else
return 0;
}
...全文
586 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
oyljerry 2018-01-20
  • 打赏
  • 举报
回复
多增加一下日志,看是否有地方忘记关闭句柄
smwhotjay 2018-01-20
  • 打赏
  • 举报
回复
逻辑理清楚,把关闭句柄写成一个函数, 把握好全局流程。
red-fly 2018-01-20
  • 打赏
  • 举报
回复
//事件处理 EventInit(); break; //跳出循环 } //PID 这里跳出循环后,读写句柄都没有关闭。 建议在频数返回之前,把所有没有关闭的句柄进行关闭
zgl7903 2018-01-20
  • 打赏
  • 举报
回复
你自己分析一下 中间的那个 break 会导致什么样的情况

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧