最近事少,尝试做一个控件容器,下载一个微软的代码来研究,不得法,于是建一个新工程,把重要代码一点点拷过去,总算要完成最基本的功能了,然而在程序退出时显示一个内存泄漏。不大,只有4个字节,心中很不爽,找一些调试内存泄漏的文章来看,大部分说用_CrtDumpMemoryLeaks()什么的,还说在vs里,默认的就能把内存泄漏的地址,包括源代码行告诉你,我看了一下,只给出地址,没给出行。反复执行多次,发现都是在同一个地址处泄漏,这就好办了,在该地址处下内存断点,需要在程序运行起来后设置。经过这么一试,发现原来的代码在一个函数内完成了这几个字节的分配和释放,而我建的程序则是只分配不释放。经过一系列折腾,发现了内存分配函数malloc和_malloca的区别,malloc不设置堆标志,而_malloca则会设置堆内存标志。再看释放,_freea函数会根据是否有堆标志来决定是否来释放内存,由于我是用malloc来分配的内存,没有设置堆标志,而在用_freea来释放时又发现没有这个标志而不去释放,结果造成了泄漏。在vs里,不论是_malloca还是_freea,都是一个宏定义,最终是否真正分配或者释放内存,还看是不是真正调用了malloc和free,这就要跟到mfc以及crt的程序里去看,并结合内存监视,看看内存有没有改变。所以我用_malloca来替代malloc来分配内存,最终问题得以解决。另外一个知识就是,堆内存需要释放,而栈内存不需要释放,或者说不需要我们来释放,这就是有些内存最后没有释放,就是因为它没有堆标志,底层代码根据这一点来决定是置之不理还是给它释放掉,看到没有堆标志,所以就把它放在那里,造成了泄漏。
一次调试内存泄漏的过程
最新推荐文章于 2024-08-11 15:55:33 发布