【发布时间】:2013-11-17 19:00:33
【问题描述】:
昨天我在 Windows 下使用 GCC 4.8.2 编译我的数字信号处理框架时遇到了内存泄漏问题。 Implementing reference counts with C++
按照建议,我尝试使用 Visual Studio 2012 编译我的代码,然后问题就解决了。我应该如何诊断这种问题?谢谢。
【问题讨论】:
标签: c++ visual-studio gcc memory-leaks
昨天我在 Windows 下使用 GCC 4.8.2 编译我的数字信号处理框架时遇到了内存泄漏问题。 Implementing reference counts with C++
按照建议,我尝试使用 Visual Studio 2012 编译我的代码,然后问题就解决了。我应该如何诊断这种问题?谢谢。
【问题讨论】:
标签: c++ visual-studio gcc memory-leaks
好吧,您可能对 VS 做出了一些错误的假设(例如,它是一个很好的编译器,当您犯错时会告诉您),并且您编写了一些不符合标准的代码。
诊断此问题的最简单方法是提高 GCC 中的警告级别:
-std=c++11 -Wall -Wextra -pedantic
让所有这些警告消失,如果运气好的话,你的泄漏就会消失。如果没有,我建议在 Linux 上编译您的代码(如果可能的话)并通过 valgrind 运行它,这将追踪困扰您的问题。
【讨论】:
在 Linux 上,您将使用 valgrind,因此在 Windows 上,您可以尝试Is there Valgrind Memcheck like tool for windows to debug use after free errors? 中建议的替代方案之一。
【讨论】:
根据我的判断,其他问题中的代码计算不正确。您在构造函数中将m_refcount 初始化为零,并在Delete 函数中将其递减。大概还有一种AddRef 或类似的函数(未显示)会增加引用计数。
在Delete 中检查的条件是refcount > 1,它偏离了1。它应该是> 0 或>= 1。
但是,我不知道为什么这适用于 Visual Studio(你确定吗?它可能不起作用,因为它不正确)。
另外你似乎不明白lock_guard 的目的。您不会在堆上分配这些,这是没有意义的。您也可以在没有lock_guard 的情况下锁定和解锁互斥锁。lock_guard 的目的是它是异常安全的,因此它必须存在于堆栈中。
【讨论】:
m_refcnt-- 抛出异常(并非不可能,因为我们对它的类型一无所知),那么函数会在锁仍然持有的情况下退出。是的,你可以通过使用 try/catch 块来解决这个问题,但有什么意义呢?对象应尽可能基于堆栈。
lock_guard 将在函数返回时(或超出范围时)或在堆栈展开时被销毁.如果您动态分配它,则情况并非如此,这使得使用lock_guard 的整个目的都过时了。