MFC_ CString 直接转LPCSTR会内存泄漏吗? 帮忙看看,谢谢!

gordonlj 2018-06-13 04:47:57
编写了一个MFC对话框程序,最近在检测_crtDumpMemoryLeaks检测内存泄漏时,发生大量的(有100多处)内存泄漏

f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(156) : {168} normal block at 0x008622A8, 24 bytes long.
Data: < T T > A0 D7 80 58 03 00 00 00 03 00 00 00 01 00 00 00

用windbg监控了一下,内存泄漏如下:
ea37d6 NTIS!CHandleMap::FromHandle+0x00000196
e14598 NTIS!CWnd::FromHandle+0x00000038
e3a1e9 NTIS!COleControlContainer::GetDlgItem+0x00000029
e3a5bc NTIS!COleControlContainer::SetDlgItemTextA+0x0000001c
e35fac NTIS!CWnd::SetDlgItemTextA+0x0000006c

在WinUser.h中,SetDlgItemTextA的变量类型是LPCSTR(const char*),我使用的都是CString的对象,
这样会产生内存泄漏吗?

strcore.cpp 的 156 行是freedata(GetData()); 具体代码如下,这个是release时候出错啦,为什么会出现这种情况?
void CString::Release()
{
if (GetData() != _afxDataNil)
{
ASSERT(GetData()->nRefs != 0);
if (InterlockedDecrement(&GetData()->nRefs) <= 0)
156 FreeData(GetData());
Init();
}
}

PS:windbg还检测出如下问题,OnWndMsg发生内存泄漏,迷茫,帮忙看看,谢谢!
e16374 NTIS!CWnd::DefWindowProcA+0x00000034
e1441d NTIS!CWnd::Default+0x0000003d
e4e2e4 NTIS!CDialog::HandleInitDialog+0x000000e4
e194a1 NTIS!CWnd::OnWndMsg+0x00000841
e18c12 NTIS!CWnd::WindowProc+0x00000032
de87e1 NTIS!CNTISDlg::WindowProc+0x000000d1
...全文
924 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
tiger波波 2018-07-18
  • 打赏
  • 举报
回复
引用 17 楼 gordonlj 的回复:
[quote=引用 16 楼 youyingbo 的回复:]
按理说CString简单使用不会导致内存泄漏的。以前见过一个论坛上讨论的,貌似最后是因为Unicode和ASC字符集交叉使用造成的。


这种问题怎么处理?我的程序开始用的是Unicode ,后来增加一个程序模块,模块用的是C,将程序转成Multi-byte。[/quote]
他貌似是dll里和调用程序之间字符编码不一致
gordonlj 2018-07-17
  • 打赏
  • 举报
回复
引用 16 楼 youyingbo 的回复:
按理说CString简单使用不会导致内存泄漏的。以前见过一个论坛上讨论的,貌似最后是因为Unicode和ASC字符集交叉使用造成的。


这种问题怎么处理?我的程序开始用的是Unicode ,后来增加一个程序模块,模块用的是C,将程序转成Multi-byte。
gordonlj 2018-06-15
  • 打赏
  • 举报
回复
引用 11 楼 smwhotjay 的回复:
要保证所有申请的变量内存在退出时都释放了。
vs2010下调试,是没有内存泄露的,现在不知道是哪里的泄露,new和malloc都释放啦。编程的时候都没有用指针,就怕泄露,还是来啦
tiger波波 2018-06-15
  • 打赏
  • 举报
回复
按理说CString简单使用不会导致内存泄漏的。以前见过一个论坛上讨论的,貌似最后是因为Unicode和ASC字符集交叉使用造成的。
赵4老师 2018-06-15
  • 打赏
  • 举报
回复
理解讨论之前请先学会如何观察! VMMap 是进程虚拟和物理内存分析实用工具。http://technet.microsoft.com/zh-cn/sysinternals/dd535533
赵4老师 2018-06-15
  • 打赏
  • 举报
回复
请牢记:源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要,重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。 意思是你程序结构看上去再合理,再简洁,也不一定比看上去一团乱麻的程序结构在运行或修改时更不易出错,更方便修改,出错了更容易找到哪里出错和具体出错的原因,更容易改正错误。 试对比 图书馆(对图书的分类够结构化了吧) 和 搜索引擎(可看作是扁平化任何结构数据,仅支持全文检索) 哪个处理信息更方便、更高效。 所以 与其费劲去重构代码让其看上去更简洁、更合理 不如费劲学习grep、sed、awk、……这类全文搜索和批处理编辑的工具。 结构越复杂,越难修改,越难除错。 有时(甚至大多数时候),看上去越合理、越简洁的代码,运行起来性能越差,出错时查找原因越难,找到出错原因后改正越费劲。 程序员要做的不是尽力避免错误,而是聚焦在快速发现并改正错误。真正以快速方式轻易解决错误,“快速的失败”远胜过“预防错误”。Fred George 前微软C#编辑器的开发主管Jay Bazuzi列出的一些有助于找到正确方向的问题;他觉得前同事们应该用这些问题来问自己;实际上不管在哪里工作的开发者们都应该经常问问自己这些问题: ◆“要保证这个问题不会再出现,我该怎么做?” ◆“要想少出些Bug,我该怎么做?” ◆“要保证Bug容易被修复,我该怎么做?” ◆“要保持对变化的快速响应,我该怎么做?” ◆“要保证我的软件的运行速度,我该怎么做?” 如果大多数团队都能不时问一下自己,必定会从中得益,因为这些都是真正强而有力的问题。
蒋晟 2018-06-15
  • 打赏
  • 举报
回复
_crtDumpMemoryLeaks 是直接把没有释放的内存当泄漏所以要在应用程序的最后执行,OnDestroy是肯定不行的。 全局变量会被误报这个没办法,不过有全局变量的程序并不是个好的设计,这样的代码单元测试性差。
gordonlj 2018-06-14
  • 打赏
  • 举报
回复
引用 9 楼 cvbtvbwu 的回复:
联系我。
已添加Q,谢谢!
叶恭介叶恭介 2018-06-14
  • 打赏
  • 举报
回复
联系我。
schlafenhamster 2018-06-14
  • 打赏
  • 举报
回复
// add this in the end of the program for auto testing of leaks and heap consistency // by default, now it is checked, since the crt memory settings are: // _CRTDBG_ALLOC_MEM_DF == _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); // If _CRTDBG_LEAK_CHECK_DF is on, then automatically leaks are tested @ exit // _CrtCheckMemory is not for leaks but for buffer under/overruns etc #define TSEKIT_LEAKZ() \ _ASSERTE( _CrtCheckMemory( ) ); \ _CrtSetDbgFlag(_CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ) | _CRTDBG_LEAK_CHECK_DF); \ // _CrtDumpMemoryLeaks(); will be auto called by CRT #else // release versions #define TSEKIT_LEAKZ() //////////////////////////////////////////////////////////////////////// int CxxxxApp::ExitInstance() { // TODO: Add your specialized code here and/or call the base class TSEKIT_LEAKZ(); // return CWinApp::ExitInstance(); }
gordonlj 2018-06-14
  • 打赏
  • 举报
回复
引用 5 楼 schlafenhamster 的回复:
1 不要 手工 调用 ,(不必调用) 2 在 app exit 中 调用试试
您好,没有理解你意思,在exit中调用?
gordonlj 2018-06-14
  • 打赏
  • 举报
回复
引用 4 楼 jiangsheng 的回复:
operator LPCSTR 不过是返回内部缓冲区地址,又不会分配内存,哪来的内存泄漏…… 这内部缓冲区会在析构的时候自动释放的,除非你有内存访问越界bug把内部缓冲区指针给覆盖掉了……
内存分配由系统自动分配吧,访问的时候,依据变量访问; 还有一个问题请教一下: 在主对话框启动时, 在OnInitDialog函数里,也发生strcore.cpp(156)内存泄漏,我很奇怪,我的代码都没执行,应该是只运行了全局变量,怎么会泄漏呢?谢谢!
smwhotjay 2018-06-14
  • 打赏
  • 举报
回复
要保证所有申请的变量内存在退出时都释放了。
schlafenhamster 2018-06-14
  • 打赏
  • 举报
回复
1 不要 手工 调用 ,(不必调用) 2 在 app exit 中 调用试试
蒋晟 2018-06-13
  • 打赏
  • 举报
回复
operator LPCSTR 不过是返回内部缓冲区地址,又不会分配内存,哪来的内存泄漏…… 这内部缓冲区会在析构的时候自动释放的,除非你有内存访问越界bug把内部缓冲区指针给覆盖掉了……
gordonlj 2018-06-13
  • 打赏
  • 举报
回复
引用 2 楼 schlafenhamster 的回复:
“_crtDumpMemoryLeaks” 手工 调用 的 地方 不对 ?
我的是一个对话框程序,我在OnDestory中 CDialogEx::OnDestroy();的前面调用的; 根据提示的strcore.cpp的156行,是CString的对象没有release掉,导致内存泄露,局部变量应该不需要管理,全局CString变量需要释放吗?怎么释放?谢谢!
paschen 2018-06-13
  • 打赏
  • 举报
回复
不会!
schlafenhamster 2018-06-13
  • 打赏
  • 举报
回复
“_crtDumpMemoryLeaks” 手工 调用 的 地方 不对 ?

15,980

社区成员

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

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