我有一个Win32 MFC应用程序,它创建一个侦听RS232端口的线程。收到新数据时,侦听器线程使用new
分配内存,并使用PostMessage
将消息发布到窗口。这很好,窗口处理传入的数据,并根据需要使用delete
删除内存。当我的程序关闭时,我注意到一些小的内存泄漏。我怀疑是一个或两个最终消息正在发布,并且在用户关闭程序并且线程在该内存被正确删除之前关闭时仍然位于消息队列中。有没有办法在程序结束前确保某些事情发生?我可以确定消息队列是空的还是至少处理了一些重要消息?我曾尝试在析构函数和类似的东西中查看WaitForInputIdle
或PeekMessage
。有什么想法可以解决这个问题吗?
答案 0 :(得分:1)
我100%同意所有已分配的内存应明确免费。 (就像你应该修复所有编译器警告一样)。这消除了诊断噪音,使您能够快速发现实际问题。
根据Harry Johnston的建议,我会将所有新数据推送到某种队列中,只需发布命令“检查队列”,删除并释放消息处理程序中的数据。这样,您可以在退出之前轻松释放队列中剩余的所有内容。
答案 1 :(得分:1)
对于小型实用程序,泄漏可能是可以接受的 - 但它可能涵盖其他不太良性的原因。
PostMessage
不保证交付。所以其他选择
SendMessage
(远程代码审核:如果PostMessage
返回false,你会立即删除内存吗?)
答案 2 :(得分:0)
人们争论不担心它有一个有效的观点。这个过程即将结束,操作系统将释放所有内存,所以花时间清理并没有多大意义。
然而,这确实会产生噪音,可能会掩盖在应用程序退出之前可能成为真正问题的持续内存泄漏。这也意味着你的程序很难变成一个可以在以后合并到另一个应用程序中的库。
我是编写干净关闭代码的粉丝,然后,在opt版本中,添加一个早期版本以跳过不必要的工作。因此,您的调试版本将告诉您真正的泄漏,您的用户将获得响应退出。
干净利落地做到这一点:
您需要一种方法让主线程告诉侦听器线程退出(或至少停止侦听)。否则你将总是有一个小机会窗口,其中主线程与退出有关,就像监听器进行另一次分配一样。主线程需要知道侦听器线程已收到并遵守此消息。只有这样,主线程才能通过队列释放与最后消息相关的所有内存,并且知道不会再有任何内存到达。
不要使用TerminateThread,否则你最终会遇到其他问题!如果侦听器线程在句柄上等待代表串行端口,那么您可以在两个句柄上等待:串行端口句柄和事件句柄。主线程可以在希望侦听器退出时引发事件。侦听器线程可以引发一个不同的事件来表示它已停止侦听。
当主线程获得WM_QUIT时,它应该引发事件以告诉侦听器退出,然后等待表示侦听器线程完成的事件,然后使用PeekMessage来提取侦听器在停止之前发布的任何消息并释放与他们相关的记忆。