class A
{
public:
unique_ptr<int> m_pM;
A() { m_pM = make_unique<int>(5); };
~A() { };
public:
void loop() { while (1) {}; } // it means just activating some works. for simplifying
};
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
A a;
a.loop(); // if i use force quit while activating this function, it causes memory leak
}
假设VS宏只检测到内存泄漏。我认为如果我在循环中使用exit(),就没有办法防止内存泄漏。因为exit()不调用析构函数,所以unique_ptr不能释放他分配的内存。
我说的对吗?或者当使用exit()时,是否有其他方法来调用析构函数?
2条答案
按热度按时间mf98qq941#
a.loop()
是一个无限循环,因此之后的所有代码都无法访问,因此编译器有权删除调用a.loop()
之后的所有代码。请参阅compiler explorer以获取证明。fnatzsnv2#
我相信在一些小众和非常罕见的场景之外,像你在这里写的那样真正的无限循环是非常无用的,因为它们的字面意思是“无限循环”。那么编译器应该做什么呢?在某种意义上,它只是推迟了对象的销毁,直到将来的某个无限时间。你通常要做的是在这样的循环中使用
break
,并在满足某些条件时中断。一个简单的例子:https://godbolt.org/z/sxr7eG4W1在这里你可以看到unique_ptr::default_delete在反汇编中,也可以看到编译器实际上在检查循环中的条件。extern volatile用于确保编译器不会优化掉标志,因为它是一个简化的例子,编译器足够聪明,可以发现标志没有改变。在真实的代码中,我建议不要使用volatile。只需检查停止条件。就是这样。