在C++中,如果我希望在发生错误时调用代码,我可以将代码放在析构函数或try-catch中。
在C语言中是否有类似的技术,使得当程序意外终止时可以调用特定的例程(以清理资源)?
在C++中,如果我希望在发生错误时调用代码,我可以将代码放在析构函数或try-catch中。
在C语言中是否有类似的技术,使得当程序意外终止时可以调用特定的例程(以清理资源)?
atexit
,该函数允许您指定一个不带参数的void
函数,在程序终止时调用(概念上,当第一次调用main
的结束括号}
被执行时)。如果您想在某些特定行为上调用特定例程,可以尝试处理信号:sigaction(2)。
以下是一个例子,其中有人想要处理分段错误: 分段错误处理
一个简单的处理CTRL + c的示例:
#include <signal.h>
#include <stdio.h>
void handle_signal(int);
int main(int argc, char* argv[])
{
//Setup Signal handling
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handle_signal;
sigaction(SIGINT, &sa, NULL);
...
}
void handle_signal(int signal)
{
switch (signal) {
case SIGINT:
your_cleanup_function();
break;
default:
fprintf(stderr, "Caught wrong signal: %d\n", signal);
return;
}
}
正如评论中所述,有许多不同的signal(7)可供使用。
atexit
的回答是互补的:atexit
适用于正常终止,而信号处理程序适用于(大多数)异常终止。 - Sneftelfprintf()
不是异步信号安全的,不能在信号处理程序中安全地调用。请参见 http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04 - Andrew HenleC 中没有像析构函数或 try-catch 块这样的功能。 您只需简单地检查函数返回值并清理资源。
通常,C 程序员使用臭名昭著的 goto 语句跳转到清理代码。
void foo()
{
if (!doA())
goto exit;
if (!doB())
goto cleanupA;
if (!doC())
goto cleanupB;
/* everything has succeeded */
return;
cleanupB:
undoB();
cleanupA:
undoA();
exit:
return;
}
exit
时,atexit
函数将被触发。 - Basile Starynkevitch