2017-01-15 3 views
0

Also habe ich etwas Code geschrieben, um die Shell (Linux, GCC, C Sprache) zu implementieren und es funktioniert alles, aber aus irgendeinem Grund stürzt der Code, wenn ich die History-Option hinzugefügt: Es tut wirklich nicht 't (der andere Code) also lege ich hier nur was du brauchst.Geschichte in der Implementierung der Shell Get Segmentierung Fehler

Das Problem ist, wenn ich quit nach einem alten Befehl eingeben, die im Verlauf gespeichert werden müssen, und wenn ich es beende, zerquetscht es nur mit Segmentierungsfehler (core dumped).

Die Geschichte ist in einer Struktur einer verketteten Liste gespeichert, string Kommando- und der Knoten für den nächsten Knoten, ebenfalls gespeichert I den Kopf in der Hauptleitung. Der Punkt ist, dass ich nur 15 letzte Befehle speichern möchte und mir die anderen nicht wichtig sind. Deshalb habe ich jedes Mal, wenn ich die Liste drucken möchte, die ersten 15 Knoten in der Schleife bewegt.

Als ich mit GDB ausgetestet sah ich, dass die Linie der Code abstürzt ist die Linie, nachdem er die die Geschichte des ersten Befehls hinzufügen, aber die aktuelle Zeile ist wirklich nicht auf die Geschichte bezogen werden:
Haupt:

int main() 
{ 
    history_ll* top; 
    char userInput [CHOICE_LENGTH]; 
    char buff[PATH_MAX]; 
    int flag=1; 
    cmdLine * head; 
    while (flag) 
    { 
     getcwd(buff, PATH_MAX); 
     printf("%s:~$ ",buff); 
     fgets(userInput,MAX_INPUT, stdin); 
     userInput[strlen(userInput)-1]=0; 
     historyAdder(userInput,&top); 
     if(strcmp(userInput,QUIT_OPTION)==0) //segmentation fault here! 
     { 
      flag=0; 
     } 
     else 
     { 
      //doesn't matter 
     } 

    } 
    return 0; 
} 

die historyAdder sieht wie folgt aus:

void historyAdder(const char *command,history_ll** top) 
{ 
    history_ll* node; 
    strcpy(node->command,command); 
    node->command[strlen(command)]=0; 
    if(historyLength!=0) 
    { 
     node->next= *top; 
    } 
    else 
    { 
     node->next= NULL; 
    } 
    *top = node; 
    historyLength++; 
} 

HINWEIS: historyLength eine globale Variable ist

Das ist die Struktur:

typedef struct history_ll{ 
    char command[CHOICE_LENGTH]; 
    struct history_ll *next; 
}history_ll; 

Danke Helfer!

Antwort

0

hier (und in den folgenden Zeilen)

void historyAdder(const char *command,history_ll** top) 
{ 
    history_ll* node; 
    strcpy(node->command,command); 
    ... 

der Code dereferenziert einen uninitialised Zeiger: node Doing so ruft UB und meistens wahrscheinlich das Programm abstürzt.

0

Dies ist wahrscheinlich Ihr Problem:

char userInput [CHOICE_LENGTH]; 
... 
fgets(userInput,MAX_INPUT, stdin); 

Sofern CHOICE_LENGTH größer oder gleich MAX_INPUT, fgets kann über das Ende des userInput Array schreiben, das wird Speicher beschädigt, zu einem Absturz führt. Da Sie jedoch kein vollständiges Programm zeigen, das ich für mich selbst kompilieren könnte, kann ich mir nicht sicher sein.

Zwei Stücke Ratschläge für Sie:

  • Sie auf Linux sind, so haben Sie getline. Verwenden Sie es anstelle von fgets, und Sie müssen sich keine Gedanken über die Größe des Eingabepuffers machen.

  • Wenn Sie ein Programm haben, das mit Segmentierungsfehlern abstürzt, sollten Sie als Erstes erreichen. Sehr oft wird Valgrind zeigen, dass der echte Bug nirgends ist, wo Sie dachten, dass es war.

1

Es gibt mindestens zwei wichtige Probleme in diesem Code. Ein ist, dass Pufferlänge möglicherweise zu kurz ne, wenn Sie von stdin lesen: Definition:

char userInput [CHOICE_LENGTH]; 

aber Nutzung ist:

fgets(userInput,MAX_INPUT, stdin); 

Sie sollten gleiche Puffergröße verwenden oder behaupten MAX_INPUT kleiner oder gleich CHOICE_LENGTH.

Zweitens lösen Sie nicht definiertes Verhalten von uninitialised Zeiger hier dereferencing:

void historyAdder(const char *command,history_ll** top) 
{ 
    history_ll* node; 
    strcpy(node->command,command); /* bad... */ 
Verwandte Themen