分段错误:11似乎不寻常

时间:2012-10-17 17:09:30

标签: c segmentation-fault

请帮我找到这个“分段错误:11”。 argv输入看起来很好。顺便说一句,这是一个餐饮哲学家的问题。它是在工作小时前,但在minix机器上,但现在在Unix机器上它不运行。请帮我解决这个愚蠢的错误。

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

#define N   5 
#define REPETITIONS 10 
#define EATTIME 3000000
#define THINKTIME EATTIME * 3 
#define LEFT    (i+N-1)%N
#define RIGHT   (i+1)%N
#define HUNGRY   1
#define EATING   2
#define THINKING 0
#define mutex   "mutex"
#define mutexLock "mutex.lock"
#define Output "output" 
#define states "states"
#define statesLock "states.lock"
#define binarySemaphore "semaphore"
#define binarySemaphoreLock "semaphore.lock"
#define up(lock) unlink(lock)
#define down(lock1,lock2) while(link(lock1,lock2)== -1);

void readFile(int numberFromFile[],char *file); /* declaring readfile() */
void writeFile(int numberToFile[],char *file);  /* declaring writeFile() */
void setPhilosopher(int i,int number);      /* declaring setPhilosopher() */
void take_Forks(int i);             /* declaring take_Forks() */
void downPhilosopher(int i);            /* declaring downPhilosopher() */
void thinking(int j);               /* declaring thinking() */
void setState(int i,int number);        /* declaring setState() */
void test(int i);               /* declaring test() */
void philosopher(int i);            /* declaring philosopher() */
void eating(int j);             /* declaring eating() */
void put_Forks(int i);              /* declaring put_Forks() */
int argNo(char *argv);              /* declaring arg number() */



int main(int args,char *argv[])
{
    int i;              /* declaring i*/
    i = argNo(argv[1]);     /* assigning argument number to i*/ 
    if((i < 0) || (i >= N))
    {
        fprintf(stderr,"Input not valid\n");    /* displays an error message*/
                            /* when number is less than 0*/
                            /* number is more than N */
    }
    else
    {   
        if((i < N) && (i >= 0))     /* else calls the philosopher function*/
            philosopher(i);     /* and passes the number to it */
//          printf("Hello %d\n", i);
    }   
}


int argNo(char *argv)
{
    int number;         /* declaring number*/
    sscanf(argv,"%d",&number);  /* gets number from the command line */
    return number;          /* return number*/
}


void philosopher(int i)
{                               
    int j;                  /* declaring j*/

    for(j = 0; j < REPETITIONS; j++)
    {                           
        thinking(i);            /* invoking thinking function*/
        take_Forks(i);          /* invoking take_Forks function*/
        eating(i);          /* invoking eating function*/
        put_Forks(i);           /* invoking put_Forks function*/
    }
}

void thinking(int j)
{
    int i,pid;              /* declaring i and pid */
    FILE *fp = fopen(Output,"a+");      /* creating and opening a file*/
    pid = getpid();             /* getting process id*/
    for(i = 0;i < THINKTIME ; i++);     /* philosopher is thinking */
    fclose(fp);             /* closing the file*/
}


void take_Forks(int i)
{
    down(mutex,mutexLock);      /* entering critical region*/
    setState(i,HUNGRY);     /* setting State to hungry */
    test(i);            /* invoking test function*/
    up(mutexLock);          /* exit critical region*/
    downPhilosopher(i);         /* invoking downPhilosopher function*/

}



void eating(int j)
{
    int i;                      /* declaring i as an int */
    int pid = getpid();             /* getting the process ID */
    FILE *fp = fopen(Output,"a+");          /* creating and opening file */
    fprintf(fp,"%d %d eating\n",pid,j);         /* writing a message to a file*/
    fprintf(stdout,"%d %d eating\n",pid,j);     /* displaying to stdout*/
    fflush(fp);                 /* flushing file*/
    for(i = 0; i < EATTIME; i++);           /* philosopher eating*/ 
    fprintf(fp,"%d %d done eating\n",pid,j);    /* writing message to file*/    
    fprintf(stdout,"%d %d done eating\n",pid,j);    /* displaying to stdout*/
    fflush(fp);                 /* flushing file*/
    fclose(fp);                 /* closing file*/
}




void put_Forks(int i)
{               
    down(mutex,mutexLock);      /* entering critical region*/
    setState(i,THINKING);       /* setting state to thinking */ 
    test(LEFT);         /* checks if left and right */
    test(RIGHT);            /* philosophers want to eat */
    up(mutexLock);          /* exit critical region*/
}



void downPhilosopher(int i)
{               
   int semaphores[N];              /* declaring semaphore array*/   
   do
   {
     readFile(semaphores,binarySemaphore); /* reading binarySemaphore into semaphore */
   }while(semaphores[i] == 0);         /* spin locks if semaphore is 0 */

   setPhilosopher(i,0);            /* setting the philosopher's state to 0*/
}

void setState(int i,int number)
{                       
    int theStates[N];           /* declaring States array*/
    down(states,statesLock);        /* enters critical region*/
    readFile(theStates,states);     /* read states from file*/
    theStates[i] = number;          /* changing the state */
    writeFile(theStates,states);        /* writes a state to a file*/   
    up(statesLock);             /* exit critical region*/
}


void test(int i)
{               
    int theStates[N];           /* declaring theStates array*/
    down(states,statesLock);        /* enters critical region*/
    readFile(theStates,states);         /* read file states*/
    up(statesLock);             /* exit critical region*/
    if(theStates[i] == HUNGRY && theStates[LEFT] != EATING &&
                theStates[RIGHT] != EATING)
    {
        setState(i,EATING); /* set the state of philosopher to eating*/
        setPhilosopher(i,1);    /* set the semaphore to 1*/
    }
}



void setPhilosopher(int i,int number)
{
    int semaphores[N];                          /* declaring semaphores[]*/ 
    down(binarySemaphore,binarySemaphoreLock);  /* enters critical region*/
    readFile(semaphores,binarySemaphore);       /* reading from file*/
    semaphores[i] = number;             /* updates the semaphore array*/
    writeFile(semaphores,binarySemaphore);      /* writing semaphore to file*/
    up(binarySemaphoreLock);            /* exit critical region*/
}


void readFile(int numberFromFile[],char *file)
{ 
    FILE *fp = fopen(file,"r");         /* creating and opening file*/
    int i;                  /* declaring i as int */
    for(i = 0; i< N; i++)
    fscanf(fp,"%d",&numberFromFile[i]);     /* reading from file into*/
                        /* numberFromFile array*/
    fclose(fp);                 /* closing the file*/
}


void writeFile(int numberToFile[],char *file)
{
    FILE *fp = fopen(file,"w");     /* creating and opening a file */
    int i;                  /* declaring i as int */
    for(i = 0; i< N; i++)                   
        fprintf(fp,"%d\n",numberToFile[i]); /* writing  */ 
                                /* numberToFile array to file*/
    fclose(fp);                     /* closing the file*/
}

3 个答案:

答案 0 :(得分:1)

此处的逻辑不会完全验证输入:

i = argNo(argv[1]);

如果我没有提供参数,你的代码期望一个数字作为命令行的第一个参数,我可以复制一个段错误。

快速修复可能是在尝试引用argv [1](可能没有提供)之前检查argc(或代码中的“args”)的大小。

答案 1 :(得分:1)

或尝试在gdb下运行

$ gcc -g myprogram.c

(gdb) run
Starting program: /home/b3h3m0th/a.out 

Program received signal SIGSEGV, Segmentation fault.
rawmemchr () at ../sysdeps/i386/rawmemchr.S:116
116     ../sysdeps/i386/rawmemchr.S: No such file or directory

尝试搜索有关该错误的错误报告。

答案 2 :(得分:0)

在这个地方,评论与代码不符:

void readFile(int numberFromFile[],char *file)
{
    /* FILE *fp = fopen(file,"r");         /* creating and opening file*/
    FILE *fp = fopen(file,"w+");         /* creating and opening file*/

一些注意事项:

  • 在ALLCAPS中使用预处理器宏是个好习惯,这使得它们易于识别
  • (全局)具有1个字母名称(N)的常量很难搜索
  • 始终将宏参数括起来(左,右)
  • 永远不要让宏引用变量名,(左,右)
  • (也许)除了一些琐碎的东西(stderr,logfiles,全局变量)
  • (我犯了这个规则,在宏中使用了filo_count变量; - )

将fopen的模式更改为“w +”, 加上对main的一些更改(添加了fork()),还删除了许多愚蠢的评论。

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

#define MAX_PHILOSOPHER 50
#define REPETITIONS 1
#define EATTIME 3000000
#define THINKTIME (EATTIME * 3)
#define LEFT(i) (((i)+filo_count-1)%filo_count)
#define RIGHT(i) (((i)+1)%filo_count)
#define HUNGRY 1
#define EATING 2
#define THINKING 0
#define MUTEX_FILENAME "mutex"
#define MUTEX_FILE_LOCK "mutex.lock"
#define LOG_FILENAME "output"
#define STATE_FILENAME "states"
#define STATE_FILE_LOCK "states.lock"
#define SEMAPHORE_FILENAME "semaphore"
#define SEMAPHORE_FILE_LOCK "semaphore.lock"
#define up(lock) unlink(lock)
#define down(file,lock) do {;} while(link(file,lock)== -1)

void readFile(int array[],char *file);
void writeFile(int array[],char *file);
void setPhilosopher(int i,int number);
void take_Forks(int i);
void downPhilosopher(int i);
void thinking(int j);
void setState(int i,int number);
void test(int i);
void philosopher(int i);
void eating(int j);
void put_Forks(int i);
int argNo(char *argv);

unsigned filo_count=0;
int main(int argc,char *argv[])
{
    int i;

    fprintf(stderr,"argc was %d\n", argc);
    i = argv[1] ? argNo(argv[1]): -1;
    if (i < 0 || i >= MAX_PHILOSOPHER)
    {
        fprintf(stderr,"Input not valid\n");
        exit (1);
    }

    filo_count=i;
    if (0) {
        FILE *fp;
        fp = fopen(MUTEX_FILENAME, "w"); fclose(fp);
        fp = fopen(STATE_FILENAME, "w"); fclose(fp);
        fp = fopen(SEMAPHORE_FILENAME, "w"); fclose(fp);
        }

    for(i=0; i < filo_count ; i++ ) {
        if (fork()) continue;
                /* philosopher is a child process */
        philosopher(i);
        break;
        }
    fprintf(stderr,"%d Dead.\n", getpid() );
    return 0;
}

int argNo(char *argv)
{
    int number;
    sscanf(argv,"%d",&number);
    return number;
}

void philosopher(int i)
{
    int j;

    for(j = 0; j < REPETITIONS; j++)
    {
        thinking(i);
        take_Forks(i);
        eating(i);
        put_Forks(i);
    }
}

void thinking(int j)
{
    int i,pid;
    FILE *fp = fopen(LOG_FILENAME,"a+");
    for(i = 0;i < THINKTIME ; i++);     /* burn some CPU */
    fclose(fp);
}

void take_Forks(int i)
{
    down(MUTEX_FILENAME,MUTEX_FILE_LOCK);      /* enter critical region*/
    setState(i,HUNGRY);
    test(i);
    up(MUTEX_FILE_LOCK);
    downPhilosopher(i);
}

void eating(int j)
{
    int i;
    int pid = getpid();
    FILE *fp = fopen(LOG_FILENAME,"a+");
    fprintf(fp,"%d %d eating\n",pid,j);
    fprintf(stdout,"%d %d eating\n",pid,j);
    fflush(fp);
    for(i = 0; i < EATTIME; i++); /* Spin idle while eating */
    fprintf(fp,"%d %d done eating\n",pid,j);
    fprintf(stdout,"%d %d done eating\n",pid,j);
    fclose(fp);
}

void put_Forks(int i)
{
    down(MUTEX_FILENAME,MUTEX_FILE_LOCK);      /* enter critical region*/
    setState(i,THINKING);
    test(LEFT(i));         /* checks if left and right */
    test(RIGHT(i));        /* philosophers want to eat */
    up(MUTEX_FILE_LOCK);
}

void downPhilosopher(int i)
{
   int semaphores[MAX_PHILOSOPHER];
   do
   {
     readFile(semaphores,SEMAPHORE_FILENAME);
   } while (semaphores[i] == 0);         /* spin locks if semaphore is 0 */

   setPhilosopher(i,0);
}

void setState(int i,int number)
{
    int theStates[MAX_PHILOSOPHER];

    down(STATE_FILENAME,STATE_FILE_LOCK);        /* enters critical region*/
    readFile(theStates,STATE_FILENAME);
    theStates[i] = number;
    writeFile(theStates,STATE_FILENAME);        /* writes a state to a file*/
    up(STATE_FILE_LOCK);
}

void test(int i)
{
    int theStates[MAX_PHILOSOPHER];

    down(STATE_FILENAME,STATE_FILE_LOCK);        /* enters critical region*/
    readFile(theStates,STATE_FILENAME);
    up(STATE_FILE_LOCK);
    if(theStates[i] == HUNGRY
        && theStates[LEFT(i)] != EATING
        && theStates[RIGHT(i)] != EATING)
    {
        setState(i,EATING);
        setPhilosopher(i,1);
    }
}

void setPhilosopher(int i,int number)
{
    int semaphores[MAX_PHILOSOPHER];

    down(SEMAPHORE_FILENAME,SEMAPHORE_FILE_LOCK);  /* enter critical region*/
    readFile(semaphores,SEMAPHORE_FILENAME);
    semaphores[i] = number;
    writeFile(semaphores,SEMAPHORE_FILENAME);
    up(SEMAPHORE_FILE_LOCK);
}


void readFile(int array[],char *file)
{
    FILE *fp = fopen(file,"w+");         /* creating and opening file*/
    int i;
    for(i = 0; i< filo_count; i++) {
       if ( 1 > fscanf(fp,"%d",&array[i]) ) array[i] = -1;
        }

    fclose(fp);
}

void writeFile(int array[],char *file)
{
    FILE *fp = fopen(file,"w");     /* creating and opening a file */
    int i;
    for(i = 0; i< filo_count; i++)  {
        fprintf(fp,"%d\n",array[i]);
        }

    fclose(fp);
}

我没有证明上面的代码是正确的,只是它有效; - )