+ -
当前位置:首页 → 问答吧 → 其原因可能是堆被损坏,这也说明 DLLTEST.exe 中或它所加载的任何 DLL 中有 bug。

其原因可能是堆被损坏,这也说明 DLLTEST.exe 中或它所加载的任何 DLL 中有 bug。

时间:2011-12-12

来源:互联网

我在DLLTEST。exe调用DLL中的_RecordsetPtr CADO::GetRecordset(_bstr_t sql)
的时候提示堆被破坏,
_RecordsetPtr CADO::GetRecordset(_bstr_t sql)
{
m_pRecordset.CreateInstance(__uuidof(Recordset));
try{
m_pRecordset->Open(sql,m_pConnection.GetInterfacePtr(),
adOpenDynamic,adLockOptimistic,adCmdText);
}
catch(_com_error &e)
{
AfxMessageBox(e.Description());
AfxMessageBox(e.ErrorMessage());
return NULL;
}
return m_pRecordset;
}
调试后是运行到 return m_pRecordset的时候出现的错误,不知道什么,用动态mfc的话就没有问题,但是改成静态mfc的话就要出错,不知道是什么原因,在静态mfc下改如何解答这个问题呀,望高手指点一下~!

作者: l3435409   发布时间: 2011-12-12

不要在外面使用智能指针,只在dll内部使用

作者: ouyh12345   发布时间: 2011-12-12

既然是封装,那就彻底些

作者: ouyh12345   发布时间: 2011-12-12

该回复于2011-12-12 11:07:17被管理员删除

  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
#4楼 得分:0回复于:2011-12-12 11:04:03
高手呀,来个高手解答下呀

作者: zyrr159487   发布时间: 2011-12-12

一个模块一个堆,一个线程一个栈。
dll里malloc的内存,在exe里free会出错。

CRT(C运行时期库)不是使用进程缺省的堆来实现malloc(new中调用malloc)的,而是使用一个全局句柄HANDLE _crtheap来分配内存的。这个_crtheap是在XXXCRTStartUp(CRT提供的进口点函数)中创建的。 
由于CRT静态连接,则楼主的DLL里有也有一个CRT,因此也有一个_crtheap。而在dll中的new使用dll中的_crtheap句柄分配堆,在exe中的delete使用exe中的_crtheap释放堆,当然失败!

解决办法:
1。在DLL中输出一个函数给EXE调用,专门用来释放由DLL分配的内存;
2。用GlobalAlloc()代替new,用GlobalFree()代替delete;
3。使用单一的堆,分配内存使用HeapAlloc(GetProcessHeap(),0,size),释放内存使用HeapFree(GetProcessHeap(),0,p);
4。把dll和exe的Settings的C/C++选项卡的Code Generation的Use Run-time liberary改成Debug Multithreaded DLL,在Release版本中改成Multithreaded DLL;这样使用一个CRT了——MSVCRT.DLL。

作者: l3435409   发布时间: 2011-12-12