如何通过调用 main 范围之外的析构函数来正确终止 C++ 程序

问题描述 投票:0回答:2

当前的 C++ 标准是否提供任何工具来从任何地方关闭程序(例如从函数内部,如

exit()
),但尊重堆上预留的资源?

我知道

exit()
函数应该释放所有内存(或者不释放,Google 给出了两个答案),但就我而言,有必要运行析构函数来释放外部系统资源。

c++ destructor
2个回答
1
投票

try
包裹main中的主要逻辑并创建
catch(terminateException e)
,在
catch
范围内你不需要写任何东西。程序将正确完成并递归地调用所有对象的 d'tors,如果每个
free
都有
malloc
或每个
delete
都有
new
,则应该没有内存泄漏。


0
投票

假设您有一些像这样的静态和动态存储持续时间实体(只有一个翻译单元的简化示例):

struct DriverStatic
{
    DriverStatic(int id): _id{id} {}
    ~DriverStatic() { std::cout << "DriverStatic stopping: " << _id << std::endl; }
    int _id;
};

static DriverStatic ds1{1}, ds2{2};

struct DriverDynamic
{
    DriverDynamic(int id): _id{id} {}
    ~DriverDynamic() { std::cout << "DriverDynamic stopping: " << _id << std::endl; }
    int _id;
};

DriverDynamic* dn1 = new DriverDynamic{1};
DriverDynamic* dn2 = new DriverDynamic{2};

您可以注册(一个或多个)退出处理程序和(一个)终止处理程序:

int main()
{
    const int atex_result = std::atexit([]() {
        std::cout << "atexit\n";
        delete dn1;
        delete dn2;
    });
    if (atex_result != 0) {
        std::cerr << "Registration failed\n";
        return EXIT_FAILURE;
    }
    std::set_terminate([](){
        std::cout << "Unhandled exception\n" << std::flush;
        delete dn1;
        delete dn2;
        // not sure how to force static objects destruction
        std::abort();
    });
    // throw std::runtime_error("abnormal exit");
    return 0;
}

这样,当调用

std::exit()
时,您将首先销毁动态存储中的驱动程序,然后静态存储中的驱动程序将以未指定的顺序销毁。

如果程序异常终止,例如未捕获的异常,您的

terminate_handler
将触发并尝试清理动态存储。

演示

但是我不确定如何确保异常情况下正确的静态对象清理。请注意,如果您调用一些未定义的行为(例如从驱动程序的析构函数中抛出异常),您的系统可能仍然无法执行您想要的操作。

无论如何,如果您正在控制某些安全关键硬件,请不要仅仅依赖您的程序能够停止移动元素。提供心跳机制,当软件连接丢失时,联锁您的系统。

© www.soinside.com 2019 - 2024. All rights reserved.