C++:一个 std::runtime_error 对象会在 longjmp 中泄漏吗?

标签 c++ exception setjmp

假设我有一些 C++ 代码,它有一个 try-catch 块,其中 catch部分将触发跳远:

#include <stdexcept>
#include <stdio.h>
#include <setjmp.h>

void my_fun()
{
    jmp_buf jump_buffer;
    if (setjmp(jump_buffer))
        return;
    
    try {
        std::string message;
        message.resize(100);
        snprintf(&message[0], 100, "error code %d\n", 3);
        throw std::runtime_error(message);
    }

    catch (std::runtime_error &e) {
        longjmp(jump_buffer, 1);
    }
}
std::runtime_error对象是在某处动态分配的,它会泄漏为其或字符串分配的内存吗?

最佳答案

这有点复杂。关于 longjmp的有效性,the standard says:

A setjmp/longjmp call pair has undefined behavior if replacing the setjmp and longjmp by catch and throw would invoke any non-trivial destructors for any objects with automatic storage duration.

runtime_error有一个非平凡的析构函数,所以问题是异常对象是否具有“自动存储持续时间”。它不是。这表明 longjmp应该没事。
此外,exception object destruction can happen in one of two places :

The points of potential destruction for the exception object are:

  • when an active handler for the exception exits by any means other than rethrowing, immediately after the destruction of the object (if any) declared in the exception-declaration in the handler;

  • when an object of type std​::​exception_­ptr that refers to the exception object is destroyed, before the destructor of std​::​exception_­ptr returns.

longjmp不是“重投”。所以理论上,由于第 1 点,这应该没问题。
话虽如此,永远不要依赖这个 .我非常怀疑 longjmp 的实现正确处理这个问题,即使有些人这样做了,也可能不是你能预料到的。

关于C++:一个 std::runtime_error 对象会在 longjmp 中泄漏吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69092014/

相关文章:

C++:使用 longjmp 和 setjmp 安全吗?

c++ - 多维数组C++中沿维度的最小值

c++ - GetLastInputInfo() 始终为 0(零)

java - 我应该对不可变类的突变尝试抛出异常吗?如果是这样,哪个异常(exception)?

java - 不同类的 GET 类方法未调用并获取 Umbrella 异常

java - 为什么我无法在创建实例或抛出异常时调用 initCause()

c++ - fwrite 和 write 之间的主要区别是什么?

c++ - 将 C 代码注入(inject) *nix 应用程序 : replacing a function

c - 用 C 写我自己的 longjmperror()

c - C中setjmp和longjmp的实际使用