【问题标题】:Memory leaks when my code is compiled by GCC当我的代码由 GCC 编译时内存泄漏
【发布时间】: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


    【解决方案1】:

    好吧,您可能对 VS 做出了一些错误的假设(例如,它是一个很好的编译器,当您犯错时会告诉您),并且您编写了一些不符合标准的代码。

    诊断此问题的最简单方法是提高 GCC 中的警告级别:

    -std=c++11 -Wall -Wextra -pedantic
    

    让所有这些警告消失,如果运气好的话,你的泄漏就会消失。如果没有,我建议在 Linux 上编译您的代码(如果可能的话)并通过 valgrind 运行它,这将追踪困扰您的问题。

    【讨论】:

    • 感谢您的建议!我稍后会尝试。
    【解决方案2】:

    在 Linux 上,您将使用 valgrind,因此在 Windows 上,您可以尝试Is there Valgrind Memcheck like tool for windows to debug use after free errors? 中建议的替代方案之一。

    【讨论】:

    • 嗨。我已经尝试了其中一些,但由于它们需要与 Visual Studio 的代码一起编译,并且我的代码在 VS 下运行良好,它们无法正常工作......也许我需要一些泄漏检查器以附加方式工作。
    【解决方案3】:

    根据我的判断,其他问题中的代码计算不正确。您在构造函数中将m_refcount 初始化为零,并在Delete 函数中将其递减。大概还有一种AddRef 或类似的函数(未显示)会增加引用计数。
    Delete 中检查的条件是refcount > 1,它偏离了1。它应该是> 0>= 1

    但是,我不知道为什么这适用于 Visual Studio(你确定吗?它可能不起作用,因为它不正确)。

    另外你似乎不明白lock_guard 的目的。您不会在堆上分配这些,这是没有意义的。您也可以在没有lock_guard 的情况下锁定和解锁互斥锁。
    lock_guard 的目的是它是异常安全的,因此它必须存在于堆栈中。

    【讨论】:

    • 嗨。我相信引用计数机制的正确性是由数据传输层保证的,代码中没有显示。但我根据你的建议修复了它:)而且我很确定它适用于 VS 2012,因为在调试模式下观察到数据流并且内存使用处于稳定状态。至于lock_guard,我曾经认为我唯一需要做的就是让它的生命周期正确,它与堆栈或堆无关(只要我在进入函数时new它并在调用delete时出口)。所以这是错的?
    • @babel92,动态分配和释放 lockguard 的问题是你已经对它的生命周期负全部责任(所有那些讨厌的 new 和 delete 调用......)。而且,简而言之,您的生命周期管理不如编译器对基于堆栈的对象的管理好。例如,如果m_refcnt-- 抛出异常(并非不可能,因为我们对它的类型一无所知),那么函数会在锁仍然持有的情况下退出。是的,你可以通过使用 try/catch 块来解决这个问题,但有什么意义呢?对象应尽可能基于堆栈。
    • @babel92:这是“RAII 的常见应用程序”之一。您已经保证了异常安全的解锁,因为lock_guard 将在函数返回时(或超出范围时)在堆栈展开时被销毁.如果您动态分配它,则情况并非如此,这使得使用lock_guard 的整个目的都过时了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    相关资源
    最近更新 更多