背景:
struct sigaction用于为处理中断的小型C程序设置处理程序。完成第二个处理程序的实现后,当我收到“分段错误(内核已转储)”错误消息时,出现了问题。我完全以相同的方式设置了两个处理程序。在不初始化sigaction结构的情况下,第一个中断处理程序工作正常,但是,当我完成第二个处理程序的实现时,我收到了seg fault错误。
题:
为什么用memset()初始化sigaction结构有助于修复错误?
码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <string.h>
#define ALARMSECONDS 3
int numSigints = 5;
/* Handler function that prints out the current time on a SIGALRM interrupt. */
static void hdl(int signum)
{
time_t currTime;
time(&currTime);
printf("\ncurrent time is %s", ctime(&currTime));
alarm(ALARMSECONDS);//re-arm the alarm
}
/* Handler function that captures SIGINT interrupts 5 times before
actually exiting. Makes use of global variable to keep track of
number of times the interrupt was sent.
*/
static void sigint_hdl(int signum)
{
numSigints -= 1;
if(numSigints == 0)
{
printf("\nFinal Control-c caught. Exiting.\n");
exit(1);
}
else
{
printf("\nControl-c caught. %d more before program is ended.\n",
numSigints);
}
}
/* Periodically prints out the current time in Unix date format using
sigaction interrupt handling.
*/
int main(int argc, char *argv[])
{
//
// vars
//
struct sigaction act;
struct sigaction sigint_act;
memset(&act, '\0', sizeof(act));//TODO Why does this fix SEGFAULT???
//
// intro
//
printf("Date will be printed every 3 seconds.\n");
printf("Enter ^C 5 times to end the program.\n");
//
// set alarm to go off in 3 seconds
//
alarm(ALARMSECONDS);
//
// set handler of the sigaction to 'hdl' function defined above
//
act.sa_handler = hdl;
sigint_act.sa_handler = sigint_hdl;
//
// activate sigaction
//
if(sigaction(SIGALRM, &act, NULL) < 0)
{
perror("sigaction -- SIGALRM");
return 1;
}
if(sigaction(SIGINT, &sigint_act, NULL) < 0)
{
perror("sigaction -- SIGINT");
return 1;
}
//
// infinite loop
//
while(1) {
}
return 0;
}
结构中有许多字段sigaction
。将它们全部设置为零会将其设置为默认值。
如果它们不是零,则将以系统调用文档中描述的任何方式解释它们。一个示例是两个字段sa_mask
和sa_sigaction
。并且根据的值sa_mask
,sa_sigaction
将安装代码的处理程序而不是预期的信号处理程序。并且由于您没有初始化指针,所以它将具有一些垃圾值,并且将尝试不仅取消引用,而且通过垃圾指针调用函数。
因此,如果无法初始化结构,则会得到未定义的行为。有时它会起作用,有时它不会以神秘的方式发生,例如崩溃。
通过将整个结构清除为零,您可以确保将发生默认行为,该行为将由您对结构所做的任何非默认设置进行修改。
经验教训:始终清除并初始化传递给库函数的所有结构。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句