标准::shared_ptr(s) 和内存泄漏

std::shared_ptr(s) and memory leaks

本文关键字:泄漏 内存 shared ptr 标准      更新时间:2023-10-16

我的问题是当我创建 2 个共享指针时,它总是说我在运行时后有内存泄漏。

解构器或指针在执行结束时的某个时间点被调用,这意味着它们正在被销毁。

但是,输出窗口仍显示内存泄漏。

这正常吗?

注意:我也可以用一个单例来解决这个问题

(头文件)

class SRNTY_API Log
{
public:
inline static std::shared_ptr<sty::Logger>& GetEngineLogger() { return mEngineLogger; }
inline static std::shared_ptr<sty::Logger>& GetClientLogger() { return mClientLogger; }
private:
static std::shared_ptr<sty::Logger> mEngineLogger;
static std::shared_ptr<sty::Logger> mClientLogger;
};

(源文件)

std::shared_ptr<sty::Logger> Log::mEngineLogger = std::make_shared<sty::Logger>();
std::shared_ptr<sty::Logger> Log::mClientLogger = std::make_shared<sty::Logger>();
下面的更新

在这个问题的评论中,有人问我如何检查内存泄漏。我可以确认我没有使用_CRTDBG_CHECK_ALWAYS_DF标志,并且我正在调用_CrtDumpMemoryLeaks()输出泄漏量并断言值应为 0。我将展示一个代码示例。

int main(int argc, char* argv[])
{
// detect memory leaks
#if defined(DEBUG) | defined(_DEBUG)
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetBreakAlloc(0);
//int mlCount = _CrtDumpMemoryLeaks();
//wprintf(L"Number of memory Leaks: %drnrn", mlCount);
//assert(mlCount == 0);
#endif
// run main loop
_CrtDumpMemoryLeaks(); // attempted calling it here and still got memory leaks as it must release the shared pointers after it returns
return 0;
}

所以我了解到它在完全返回操作系统后释放了std::shared_ptr<T>。 但它在运行后仍然显示错误的内存泄漏。

我尝试过的其他事情是:

Singleton,我做了一个Singleton界面,我没有问题,也没有内存泄漏。然而,我不反对Singleton的,但我更喜欢使用 c++ std lib 的共享指针,因为毫无疑问它们比我的Singleton解决方案更好,而且编译器将针对 std lib 而不是我的代码进行优化。

我已经搜索了一个位置来调用CrtDumpMemoryLeaks()但是我构建代码的方式无法在日志析构函数中调用它,甚至不确定它会大喊正确的结果并且不显示内存泄漏。

(不可复制。

class INonCopyable
{
protected:
INonCopyable(void) {}
virtual ~INonCopyable(void) {}
private:
INonCopyable(const INonCopyable& other) = delete;
const INonCopyable& operator= (const INonCopyable& other) = delete;
};

(isingleton.h)

template<typename T>
class ISingleton : public INonCopyable
{
public:
inline static T& GetInstance() { if (!mInstance) { mInstance = new T(); } return *mInstance; }
inline static void DestroyInstance() { delete mInstance; mInstance = nullptr; }
private:
inline static T* mInstance = nullptr;
};

Log 类在使用时实现的方式Singleton

更改为
class SRNTY_API EngineLog : public ISingleton<EngineLog>, public sty::Logger
{
};
class SRNTY_API ClientLog : public ISingleton<ClientLog>, public sty::Logger
{
};

总结:

使用Singleton时没有内存泄漏,我可以使用它吗? 在 C++17 中线程安全吗? 如果可能的话,std::share_ptr<T>我应该何时何地调用CrtDumpMemoryLeaks()函数?或者我应该如何实现std::share_ptr<T>以避免错误的内存泄漏?

希望这能把问题:)

我只想自己回答这个问题。

首先感谢那些发表评论和提供信息的人。

使用std::shared_ptr<T>时,问题是手动调用_CrtDumpMemoryLeaks()您需要做的是使用标志_CRTDBG_CHECK_ALWAYS_DF,它会在运行结束时自动检查内存泄漏。

我最终使用的代码是:

// detect memory leaks
#if defined(DEBUG) | defined(_DEBUG)
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF) | _CRTDBG_CHECK_ALWAYS_DF); // added in _CRTDBG_CHECK_ALWAYS_DF
_CrtSetBreakAlloc(0);
#endif

希望这对未来的:)有所帮助