2016-12-07 5 views
1

Ich versuche eine globale Zeigervariable zu definieren, die dann wirklich in der Hauptfunktion wie unten gezeigt gesetzt werden kann. Ich erhalte jedoch immer einen Segmentierungsfehler, wenn ich versuche, danach outputName zu verwenden. Ich weiß, dass es wahrscheinlich damit zu tun hat, den Zeiger am Anfang gleich NULL zu setzen ... jede Hilfe, wie ich einen globalen Zeiger haben könnte, der dann in main gesetzt wird, wäre sehr hilfreich! Hier ist der Teil meiner Code, der mir Fehler geben:Segmentierungsfehler mit globalen Zeigern

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

Wie viele Argumente übergeben Sie an 'main()'? Haben Sie das grundlegende Debugging durchgeführt, um zu sehen, was der Wert von 'argv [2]' ist? Hast du "argc> = 3" überprüft? – John3136

+0

übergibt vier Argumente, ja, all diese Fehlerüberprüfung, um sicherzustellen, dass der Wert von are korrekt ist. – liverr1818

+1

Wenn also "outputName" nach dem obigen Code gültig ist, dann ist das Problem woanders ... – John3136

Antwort

3

Mai Signal-Handler sein heißt immer vor output auf nicht Null-Wert gesetzt zu werden, können Sie versuchen, Signal-Handler Einstellung nach output = argv [2] ; in main()

2

lesen sorgfältigsignal(7): da Ihre catcher Anrufe printf die kein asynchrones Signal sichere Funktion ist, muss Ihr Code undefined behavior. Außerdem endet Ihre printf Kontrollzeichenfolge nicht mit \n, und da stdout Zeile gepuffert ist, würde keine Ausgabe erfolgen. Bevorzugen Sie sigaction(2) zu signal, und installieren Sie Ihren Signalhandler nach zugewiesen outputName.

Globale Variablen, die in Signalhandlern verwendet werden, sollten als volatile deklariert werden. So deklarieren Sie Ihre char* volatile outputName; auf globaler Ebene. Dann könnten Sie einen Test wie if (outputName != NULL) remove(outputName); im Handler haben. Eine gängige Praxis besteht darin, nur ein globales Flag volatile sig_atomic_t im Signalhandler zu setzen und dieses Flag an anderer Stelle zu testen.

Und Ihr Programm wird wahrscheinlich keine Zeit haben, irgendein Signal zu bekommen. Sie sollten wahrscheinlich Ihre main Funktion mit etwas warten (z. B. lesen von stdin oder usleep(3) oder pause(2) oder poll(2) ....).

Natürlich kompilieren Sie Ihren Code mit allen Warnungen und Debug-Informationen (gcc -Wall -g) und verwenden Sie den Debugger (gdb); Ich denke, dass Debugger watchpoints sehr nützlich sein sollte, um Ihren Fehler zu finden.

Das von Ihnen angezeigte Programm zeigt wahrscheinlich kein SEGV. Ihr Fehler ist wahrscheinlich anderswo.

Vielleicht könnte auch mit und/oder valgrind helfen.