[英]Why does initializing a sigint variable with memset() help prevent Seg Faults?
背景:
struct sigaction用於為處理中斷的小型C程序設置處理程序。 在完成第二個處理程序的實現后收到“Segmentation fault(core dumped)”錯誤消息時出現問題。 我以完全相同的方式設置兩個處理程序。 第一個中斷處理程序工作正常而沒有初始化sigaction結構,但是,當我完成第二個處理程序的實現時,我收到了seg錯誤錯誤。
題:
為什么用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
處理程序而不是您的代碼安裝的預期信號處理程序。 並且由於你沒有初始化指針,它將有一些垃圾值,並且將嘗試不僅僅取消引用,而是通過垃圾指針調用函數。
因此,如果您未能初始化結構,則會得到未定義的行為。 有時它會工作,有時它不會以神秘的方式,例如崩潰。
通過將整個結構清除為零,您可以確保將發生默認行為,並通過它們對結構所做的任何非默認設置進行修改。
獲得的經驗:始終清除並初始化傳遞給庫函數的所有結構。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.