2016-12-07 17 views
1

J'essaie de définir une variable pointeur globale qui peut alors vraiment être définie dans la fonction principale, comme indiqué ci-dessous. Cependant, je reçois une erreur de segmentation à chaque fois que j'essaie d'utiliser outputName après cela. Je sais que cela a probablement à voir avec le réglage du pointeur égal à NULL au début ... toute aide sur la façon dont je pourrais avoir un pointeur global qui est ensuite défini dans main serait très utile! Voici la partie de mon code qui me donne des erreurs:Erreur de segmentation avec des pointeurs globaux

char* outputName=NULL; 

int isNumber(char number[]){ 
int i; 
if (number[0]=='-'){ 
    i=1; 
} 
while(number[i] != '\0'){ 
    if (!isdigit(number[i])){ 
    return 0; 
    } 
    i++; 
} 
return 1; 
} 

void catcher(int signo) { 
printf("The program is exiting early"); 
remove(outputName); 
exit(1); 
} 

int main(int argc, char *argv[]) { 
if (argc != 4){ 
    fprintf(stderr,"Incorrect number of arguments, must supply three.\n"); 
    exit(1); 
} 
char* inputName = argv[1]; 
outputName=argv[2]; 
signal(SIGINT, catcher); 
int result=isNumber(argv[3]); 
if (result==0){ 
    fprintf(stderr, "Invalid maximum line length, please enter an integer\n"); 
    exit(1); 
} 
int maxChars= (atoi(argv[3]))+1; 
if ((maxChars-1)<1){ 
    fprintf(stderr, "Invalid third maximum line length, please enter an integer greater than zero\           
.\n"); 
    exit(1); 
} 
FILE* inFile = fopen(inputName, "r"); 
if (inFile==NULL){ 
    fprintf(stderr,"Error while opening %s.\n", inputName); 
    exit(1); 
} 
FILE* outFile= fopen(outputName, "w"); 
if (outFile==NULL){ 
    fprintf(stderr,"Error while opening %s.\n", outputName); 
    exit(1); 
}                        
char line[maxChars]; 
int done=0; 
while (!done){ 
    char *readLine=fgets(line,maxChars,inFile); 
    if (readLine==NULL){ 
    if (errno==0){ 
     done=1; 
    } 
    else{ 
    fprintf(stderr, "Error when reading line from input file"); 
    exit(1); 
    } 
} 
int len=strlen(line); 
if (line[len-1]!='\n'){ 
    line[len]='\n'; 
    line[len+1]='\0'; 
    char current=' '; 
    while (current != '\n'){ 
    current=getc(inFile); 
    } 
} 
if (!done){ 
    fputs(line, outFile); 
    if (errno!=0){ 
    fprintf(stderr, "Error when writing line to output file"); 
    exit(1); 
    } 
    } 
} 
return 0; 
} 
+0

Combien d'arguments passez-vous à 'main()'? avez-vous fait un débogage basique pour voir quelle est la valeur de 'argv [2]'? Avez-vous vérifié 'argc> = 3'? – John3136

+0

en passant quatre arguments, oui fait toute cette vérification d'erreur pour s'assurer que la valeur de est correcte. – liverr1818

+1

Donc, si 'outputName' est valide après le code ci-dessus, alors le problème est ailleurs ... – John3136

Répondre

3

peut être gestionnaire de signal est obtenir appelé avant outputName se régler à la valeur non nulle, vous pouvez essayer de configurer le gestionnaire de signaux après outputName = argv [2] ; en main()

2

Lire attentivement signal(7): puisque vos appels catcherprintf qui n'est pas une fonction de sécurité de signal async, votre code a undefined behavior. En outre, votre chaîne de contrôle printf ne se termine pas par \n et comme stdout est mis en mémoire tampon, aucune sortie ne sera effectuée. Préférez sigaction(2) à signal et installez votre gestionnaire de signaux après ayant affecté outputName.

Les variables globales utilisées dans les gestionnaires de signaux doivent être déclarées volatile. Alors déclarez votre char* volatile outputName; à portée globale. Ensuite, vous pourriez avoir un test comme if (outputName != NULL) remove(outputName); dans le gestionnaire. Une pratique courante consiste simplement à définir un drapeau global volatile sig_atomic_t dans le gestionnaire de signal et à tester ce drapeau ailleurs.

Et votre programme n'aura probablement pas le temps d'obtenir un signal. Vous devriez probablement mettre fin à votre fonction main avec une certaine attente (par exemple lire stdin, ou usleep(3), ou pause(2), ou poll(2) ....).

Bien sûr, compilez votre code avec tous les avertissements et les informations de débogage (gcc -Wall -g) et utiliser le débogueur (gdb); Je suppose que ce débogueur watchpoints devrait être très utile pour trouver votre bug.

Le programme que vous montrez est susceptible de ne pas présenter de SEGV. Donc, votre bug réel est très probablement ailleurs.

Peut-être en utilisant strace(1) et/ou valgrind pourrait également aider.