当在头文件上而不是在CPP文件上实现时,析构函数会导致内存泄漏——仅在linux上实现

A destructor function is causing memory leak when implemented on header file rather than on CPP file - only on linux

本文关键字:实现 文件 内存 仅在 linux 泄漏 CPP 析构函数      更新时间:2023-10-16

我们管理一些多平台代码,我遇到了只在linux上发生的最奇怪的内存泄漏。

我有一个类既不继承也不被继承。由于它没有任何需要释放的动态分配,我没有为它定义析构函数(它确实有一些自毁成员,没有一个是指针)。

我们注意到这个类的生成(new)和销毁(delete)导致了内存泄漏。在头文件上定义和实现一个空的析构函数并没有解决泄漏问题。将实现移动到源文件-确实解决了它。这(泄漏)不会发生在windows上,但会发生在linux上。

我想这与编译器优化有关,但如果是这样的话,我真的想知道这个现象的基础,所以我会知道如何避免再次出现这种泄漏。

有人知道为什么会发生这种事吗?

这是代码的草图(当然不是真正的…)

//file config.h
class Config
{       
    public:
        Config(std::shared_ptr<PR_Config> prConfig)
        {mPRConfig = engineConfig; mConfigOccurences++;};
        ~Config(){}
        shared_ptr<PR_Config>...
        ...
        ...
        ...
        //some public functions
    private:
        shared_ptr<PR_Config>...
        ...
        ...
        ...
        //some private members of shared_ptr type
};

//file: ConfigChecker.cpp
bool ConfigChecker::CheckConfig()
{
    shared_ptr<Config>  localConfig;
    localConfig = GenerateConfig();
    //Do some stuff with local config. did not change the reference count...
    if (locakConfig)
        return true;
    return false;
}
//file: Utils.cpp
shared_ptr<Config>  GenerateConfig()
{
    shared_ptr<Config>  pConfig = new Config(/*som parameters here...*/)
    return pConfig;
}

重要提示:

  • 将~Config的实现移动到Config.cpp文件时,泄漏停止
  • 我们并不真正使用sharedptr,而是使用其他一些具有引用计数和自毁功能的智能指针。但我不相信它在做

我已经看到了这种由前向声明和std::auto_ptr创建的不完整类型的确切行为。

我相信shared_ptrunique_ptr的当前版本已经通过使用显式析构函数解决了这个问题,如果定义不可见,它们将无法编译。

我怀疑你的"其他智能指针"没有这样做,或者做得不对。这很难做到正确。C++标准的人发明了auto_ptr,并在解决这个问题之前使用了多年。