我的机器的 std::exception_ptr、std::current_exception 和 rethrow_exception 实现中是否存在内存泄漏?

Is there a memory leak in my machine's implementation of std::exception_ptr, std::current_exception and rethrow_exception?

提问人:Philipp B. 提问时间:11/17/2022 最后编辑:Jeff SchallerPhilipp B. 更新时间:11/23/2022 访问量:187

问:

运行以下代码时,我看到进程的内存消耗增加。我的代码中是否存在内存泄漏,std 实现中是否存在内存泄漏,或者是预期行为?它在 Windows 10 计算机上运行;Visual Studio 和任务管理器都显示每分钟大约 1MB 的内存增长。

for (int i = 0; i < 10000; i++) {

    std::exception_ptr exptr = nullptr;
    std::string errmsg = "some error";
    try {
        throw std::runtime_error(errmsg.c_str());
    }
    catch (...) {
        exptr = std::current_exception();
    }

    if (exptr) {
        try {
            rethrow_exception(exptr);
        }
        catch (std::exception const& ex) {
            exptr = nullptr;
            std::cout << ex.what() << std::endl;
        }
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(10ms));
}

当直接抛出和记录时,没有延迟(不使用),内存消耗不会增加。 被宣传为行为类似于智能指针,因此在重置它(将其设置为 )时,应销毁基础资源。因此,我希望适当地释放基础异常。std::exception_ptrstd::exception_ptrnullptr

C++ 异常 std rethrow

评论

1赞 Nelfeal 11/17/2022
“The Std Implementation” - 有多个 STD 实现。尽管可能性不大,但其中一个可能有错误。你用的是哪一个?Microsoft的“STL”?
1赞 Philipp B. 11/17/2022
@nick我只能向你保证,我是手写的,但这确实很有趣。关于您的 SO 链接,我看到了这一点,但情况有所不同(持有对 exception_ptrs 的循环引用的对象)。
2赞 Philipp B. 11/17/2022
@RaymondChen感谢您对时间旅行追踪的提示。是的,像shared_ptr一样行事可以确保,如果一个人这样做 ptr = nullptr;将调用基础对象的析构函数。
2赞 Philipp B. 11/18/2022
我发现以下几点:当我将代码复制到一个新项目中时,内存消耗不会增加。我比较了编译器选项,需要激活以下编译器选项以避免内存消耗增加:/EHa
2赞 Philipp B. 11/18/2022
从 msvc 编译器文档中,我读到:[...]默认异常展开代码不会销毁由于异常而超出范围的 try 块之外的自动 C++ 对象。引发 C++ 异常时,可能会导致资源泄漏和未定义的行为。[...]因此,不断增长的内存消耗可能是内存泄漏。

答:

0赞 Philipp B. 11/23/2022 #1

我发现以下几点:当我将代码复制到一个新项目中时,内存消耗不会增加。我比较了编译器选项,需要激活以下编译器选项以避免内存消耗增加:/EHsc

从 msvc 编译器文档中,我读到:[...]默认异常展开代码不会销毁由于异常而超出范围的 try 块之外的自动 C++ 对象。引发 C++ 异常时,可能会导致资源泄漏和未定义的行为。[...]因此,不断增长的内存消耗可能是内存泄漏。