从不兼容的指针类型分配 - 如何修复?

时间:2017-02-09 04:55:18

标签: c pointers handlers

尝试实现信号处理程序,但收到警告:

assignment from incompatible pointer type [enabled by default]
   act.sa_sigaction = sigChldHandler;

......我的教授也指出了。

char * argv[3];
argv[0]= GUESSER_PROGNAME;
argv[2]= NULL;

这为3个char指针变量分配内存,但它们并没有特别指向任何地方。"但我不确定他的意思是什么。

\ file 1

#include "assign2Headers.h"
pid_t answererPid;
pid_t guesserPid;

int shouldRun = 1;

void  sigAlrmHandler(int sig)
{
    kill(answererPid,TIME_OVER_SIGNAL);
    kill(guesserPid,TIME_OVER_SIGNAL);
    shouldRun=0;
}

void  sigChldHandler(int sig)
{
wait(NULL);
shouldRun=0;
}

int main(void){


  struct sigaction act;
  memset(&act, '\0', sizeof(struct sigaction));

  act.sa_handler = sigAlrmHandler;
  sigaction(SIGALRM, &act, NULL);

  act.sa_sigaction = sighldHandler;
  sigaction(SIGCHLD, &act, NULL);


char line[LINE_LEN];
char * argv[3];
argv[0]= GUESSER_PROGNAME;
argv[2]= NULL;
answererPid = fork();

if(answererPid == 0){

        execl(ANSWERER_PROGNAME,ANSWERER_PROGNAME,(char*)NULL);

    }

else{
        sleep(1);
        snprintf(line,LINE_LEN,"%d",answererPid);
        guesserPid=fork();
        if(guesserPid==0)
        {
            execl(GUESSER_PROGNAME,GUESSER_PROGNAME,argv[0],line,(char*)NULL);
        }
        else
        { alarm(NUM_SECONDS);
            while(shouldRun)
                sleep(1);
            sleep(1);
            sleep(1);
            printf("launcher finished\n");
            return (EXIT_SUCCESS);

        }

    }

}

\ file 2

#include "assign2Headers.h"

int shouldRun = 1;

void timeoverhandler(int sig)
{   sleep(1);
    printf("\nOh no!  The time is up!\n");
    printf("guesser finished\n");
    shouldRun=0;
    exit(EXIT_SUCCESS);
}

void winsignalhandler(int sig)
{
    printf("\nCongratulations!  You found it!\n");
    shouldRun=0;
        signal(WIN_SIGNAL,winsignalhandler);
}

void correctsignalhandler(int sig)
{
    printf("Yay!  That was right!\n");
    signal(CORRECT_SIGNAL,correctsignalhandler);
}

void incorrectsignalhandler(int sig)
{
    printf("Oops!  That was wrong.  Please restart from the beginning.\n"
"\nRe-starting from the beginning:\n");
    signal(INCORRECT_SIGNAL,incorrectsignalhandler);
}

int main(int argc,char* argv[])
{

    pid_t answererPid=atoi(argv[1]);
    signal(TIME_OVER_SIGNAL,timeoverhandler);
    signal(WIN_SIGNAL,winsignalhandler);
    signal(CORRECT_SIGNAL,correctsignalhandler);
    signal(INCORRECT_SIGNAL,incorrectsignalhandler);

    while(shouldRun)
    {   int guess;
        printf("What would you like your next guess to be: 0 or 1? ");
        scanf("%d",&guess);
        if(guess==0)
            kill(answererPid,ZERO_SIGNAL);
        if(guess==1)
            kill(answererPid,ONE_SIGNAL);
        sleep(2);

    }


    printf("guesser finished\n");
    return (EXIT_SUCCESS);


}

\ file 3

//---       Common standard header files                ---//

#include    <stdlib.h>
#include    <stdio.h>
#include    <string.h>
#include    <signal.h>
#include    <sys/types.h>
#include    <sys/wait.h>
#include    <unistd.h>

////---     Common constants:                   ---//

#define     ZERO_SIGNAL     SIGUSR1    
#define     ONE_SIGNAL      SIGUSR2
#define     CORRECT_SIGNAL      SIGUSR1
#define     INCORRECT_SIGNAL    SIGUSR2
#define     WIN_SIGNAL      SIGINT
#define     TIME_OVER_SIGNAL    SIGTERM

#define     GUESSER_PROGNAME    "guesser"
#define     ANSWERER_PROGNAME   "answerer"

#define     LINE_LEN        256
#define     NUM_SECONDS     30

\ file 4

//---       Inclusion of header files               ---//

#include    "assign2Headers.h"

//---       Definition of constants:                ---//

#define     PATTERN_LEN 4

//---       Definition of global vars:              ---//

int     answer;
int     numCorrect  = 0;
int     shouldRun   = 1;


//---       Definition of global fncs:              ---//

void        timeUpHandler   (int        sig
                )
{
  shouldRun = 0;
}


void        guessHandler    (int        sig,
                 siginfo_t* infoPtr,
                 void*      dataPtr
                )
{
  int   toSendBack;
  int   userBit     = (sig == ONE_SIGNAL);
  int   correctBit  = ((answer >> numCorrect) & 0x1);
  int   isCorrect   = (correctBit == userBit);

  printf("position %d: userBit %d, correctBit %d\n",
     numCorrect,userBit,correctBit
    );

  if  (isCorrect)
  {
    numCorrect++;

    if  (numCorrect >= PATTERN_LEN)
      toSendBack = WIN_SIGNAL;
    else
      toSendBack = CORRECT_SIGNAL;
  }
  else
  {
    numCorrect  = 0;
    toSendBack  = INCORRECT_SIGNAL;
  }

  kill(infoPtr->si_pid,toSendBack);
}


int     main        (int    argc,
                 char*  argv[]
                )
{
  //  I.  Application validity check:

  //  II.  Run program:
  //  II.A.  Initialize random number generator and choice:
  srand(getpid());

  answer    = rand() % (1 << PATTERN_LEN);

printf("(The answer is %d)\n",answer);

  //  II.B.  Install signal handlers:
  struct sigaction  act;

  memset(&act,'\0',sizeof(act));
  act.sa_handler    = timeUpHandler;
  sigaction(TIME_OVER_SIGNAL,&act,NULL);

  act.sa_flags      = SA_SIGINFO;
  act.sa_sigaction  = guessHandler;
  sigaction(ZERO_SIGNAL,&act,NULL);
  sigaction(ONE_SIGNAL,&act,NULL);

  //  II.C.  Hand out while game still active:
  while  ( (numCorrect < PATTERN_LEN)  &&  shouldRun )
    sleep(1);

  //  III.  Finished, return answer:
  printf("answerer finished\n");
  return(EXIT_SUCCESS);
}

如何删除此警告以及他的意思是什么?有人帮帮我。

2 个答案:

答案 0 :(得分:4)

我猜你正在研究Linux。来自sigaction联机帮助页:

   struct sigaction {
       void     (*sa_handler)(int);
       void     (*sa_sigaction)(int, siginfo_t *, void *);
       sigset_t   sa_mask;
       int        sa_flags;
       void     (*sa_restorer)(void);
   };

原型void sigChldHandler(int sig)sa_sigaction不匹配。因此警告。

您可以使用

  1. sa_handler设置信号处理函数或指定SIG_IGN / SIG_DFL操作。
  2. sa_sigaction设置信号处理函数 - 如果用户需要访问更多细节,如用户上下文和siginfo结构(发送者进程详细信息,信号类型等)。需要在SA_SIGINFO中为此用法设置sa_flags
  3. 对于您的情况,设置sa_handler可能就足够了。

    main()

    struct sigaction act;
    act.sa_handler = sigChldHandler;
    act.sa_flags = SA_RESTART;
    sigaction(SIGCHLD, &act, NULL);
    

    另外,

    1. 为每个要设置的信号使用单独的sigaction结构,除非您需要相同的处理程序。
    2. 不要混用sigaction()&amp; signal()用法。坚持一个。也许,sigaction因为它是新的&amp;提供的功能多于signal()

答案 1 :(得分:1)

此段:

char * argv[3]; 
argv[0]= GUESSER_PROGNAME; 
argv[2]= NULL;

argv[0]无效。由于argv是一个指针数组,因此在使用它们之前,需要确保这些指针指向某个位置。

这可以通过strdup()

来实现
argv[0]= strdup(GUESSER_PROGNAME);

或使用malloc() / strcpy()

argv[0]= malloc(strlen(GUESSER_PROGNAME)+1);
strcpy(argv[0], GUESSER_PROGNAME);

注意: malloc()也应该检查,失败时可以返回NULL。堆上分配的任何内存最后也应该是free()

就清晰度而言,您可以替换:

#define GUESSER_PROGNAME "guesser"

使用:

const char *guesser_progname = "guesser";