当前的 C++ 标准是否提供任何工具来从任何地方关闭程序(例如从函数内部,如
exit()
),但尊重堆上预留的资源?
我知道
exit()
函数应该释放所有内存(或者不释放,Google 给出了两个答案),但就我而言,有必要运行析构函数来释放外部系统资源。
用
try
包裹main中的主要逻辑并创建catch(terminateException e)
,在catch
范围内你不需要写任何东西。程序将正确完成并递归地调用所有对象的 d'tors,如果每个 free
都有 malloc
或每个 delete
都有 new
,则应该没有内存泄漏。
假设您有一些像这样的静态和动态存储持续时间实体(只有一个翻译单元的简化示例):
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
将触发并尝试清理动态存储。
但是我不确定如何确保异常情况下正确的静态对象清理。请注意,如果您调用一些未定义的行为(例如从驱动程序的析构函数中抛出异常),您的系统可能仍然无法执行您想要的操作。
无论如何,如果您正在控制某些安全关键硬件,请不要仅仅依赖您的程序能够停止移动元素。提供心跳机制,当软件连接丢失时,联锁您的系统。