2012-03-30 9 views
0

Iam, indem sie einen Parser in BisonUnerklärliche Junk-Wert in Variable

LOCATION house 
NAME "House" 
DESCRIPTION "You are standing\nin front of your house.\nPaths lead towards east and west." 
east flag 
west forest 

LOCATION obelisk 
NAME "Obelisk" 
DESCRIPTION "A big obelisk is\nstanding before you. You can either go east or west or south." 
south flag 
east flag 
west treasure 

Mein Parser eine Datei im folgenden Format zu kompilieren versuchen, hat eine Funktion

int find(char *id) { 
int i; 
for(i=0;i<nLoc;i++) { 
if(strcmp(id,tmp_idList[i]) == 0){ 
    printf(tmp_idList[0]); 
    printf(" i = %d returned",i); 
return i; 

    } 
} 

printf("Copying..."); 
strcpy(tmp_idList[nLoc],id); 
printf("%d %s",nLoc,tmp_idList[nLoc]); 
nLoc++; 
printf(" nloc-1 = %d returned",nLoc-1); 
return (nLoc-1); 
} 

Es verwendet

char tmp_idList[60][100]; 

Grammatik ist (hier relevant)

locnSpec : tok_LOCN tok_IDENT nameSpec descrSpec exitList 
      {int k = find($2); 
      locList[k].name = strdup(tmp_name); 
      locList[k].descr = strdup(tmp_descr); 
      memcpy(locList[k].exits, 
        tmp_exit, 
        4*sizeof(int));} 

Jetzt, als ich diesen Code ausführen, irgendwie

tmpidList[0] 

ist mit einem Junk-Wert gefüllt zu werden, wie in dem unten stehenden

Microsoft Windows [Version 6.1.7600] 
Copyright (c) 2009 Microsoft Corporation. All rights reserved. 



C:\Users\MY PC\Desktop\final>bison -d -o compile.c adv6.y 

C:\Users\MY PC\Desktop\final>gcc -o compile compile.c lex.yy.c 

C:\Users\MY PC\Desktop\final>compile<toy.al 



Copying...0 flag nloc-1 = 0 returned 
Copying...1 forest nloc-1 = 1 returned 

Copying...2 house nloc-1 = 2 returned 


flag i = 0 returned // OK HERE 
flag i = 0 returned 
Copying...3 treasure nloc-1 = 3 returned 

Copying...4 obelisk nloc-1 = 4 returned 



Copying...5 marsh nloc-1 = 5 returned 


nd west. i = 4 returned // JUNK HERE 
Copying...6 flag nloc-1 = 6 returned 
nd west. i = 1 returned 

nd west. i = 3 returned 


t. i = 4 returned 
t. i = 2 returned 
t. i = 4 returned 

t. i = 6 returned 


t. i = 5 returned 
t. i = 2 returned 
t. i = 3 returned 

t. i = 1 returned t. i = 2 returned 


C:\Users\MY PC\Desktop\final> 

Als Cue Ausgang gezeigt, als ich versuchte Speicher über malloc Zuteilen

char* tmp_idList[20] 

... 

tmp_idList[nLoc] = malloc(strlen(id) +1) 

es funktionierte gut, bis Flag war dort in tmp_idList [0] aber nicht mehr funktioniert und th Es gab einen Speicherfehler in compile.exe.

hat jemand Ahnung, was passiert? wenn Sie mehr Informationen wünschen, kann ich zur Verfügung stellen. Ich brauche wirklich Hilfe für mein Hochschulprojekt.

+0

Verwenden Sie * Zeichenfolge * C++ - Klasse anstelle von * char ** – m0skit0

+0

Alternativ markieren Sie keine Frage zu c mit [C++]. – dmckee

+0

Ich habe das C++ - Tag entfernt; Es schien ein Artefakt der kollektiv unbewussten mythischen Sprache "C/C++" zu sein. – aib

Antwort

1

Eine Anmerkung. Ihre find Funktion könnte intern genannt werden. Was es tut, ist ein String-Token auf ein numerisches Atom zu reduzieren. Wenn es die Zeichenfolge zuvor nicht gesehen hat, gibt es ein neues Atom zurück, aber wenn es zweimal mit derselben Zeichenfolge aufgerufen wird, gibt es jedes Mal das gleiche Atom zurück. Dies nennt man Internieren, das in der Lisp-Sprache entstanden ist.

Sie haben einige Probleme in diesem Code, da Ihre Symbole Platz für 100 Charakternamen haben, aber Sie überprüfen dies nicht und verwenden nur blind strcpy.

Jetzt über diese Grammatikregel:

locnSpec: tok_LOCN tok_IDENT nameSpec descrSpec Ausgangslisten {int k = find ($ 2); locList [k] .name = strdup (tmp_name); locList [k] .descr = strdup (tmp_descr); memcpy (locList [k] .exits, tmp_exit, 4 * sizeof (int));}

Was passiert, wenn ein Standort spec zweimal für die gleiche Stelle auftritt? Sie verlieren diesen Speicher nur, indem Sie locList[k].name überschreiben. Vielleicht möchten Sie den alten Wert freigeben, der vorher dort war. Wenn diese Strukturen auf Null/Nullen initialisiert werden, können Sie Folgendes tun:

free (locList [k] .name); locList [k].name = strdup (tmp_name);

Zweitens, woher kommen diese tmp_name und tmp_descr Variablen? Sind diese Globalen, die während der Reduktion der namesSpec und descrSpec Nichtterminalsymbole mit Werten gefüllt wurden?

Das ist ein hässlicher Ansatz; Sie sollten wirklich den Yacc-Stapel verwenden, um semantische Werte zurückzugeben und auf sie über $ 3, $ 4 und $ 5 zu verweisen.

Wie für das Korruptionsproblem Sie jagen; Es ist möglicherweise ein statischer Array-Overrun. Sie machen keine Grenzen, wenn Sie nach etwas suchen.

Der Kern des Problems ist dies:

/* two arrays, probably located side by side in the executable image */ 
static char array1[20][30]; 
static char array2[40][20]; 

Wenn Sie array1 über sein Ende zugreifen, werden Sie wahrscheinlich eine andere Variable Müll, wie vielleicht array2, je nachdem, wie die Dinge im Vorfeld gelegt Zeit Bild.

Eine Sache, die Sie tun können, ohne erweiterte Debugging-Tools, besteht darin, den Code im Debugger zu durchlaufen und den Inhalt der überschriebenen Variablen zu überwachen. Versuchen Sie, das Programm "red handed" zu fangen, indem Sie diesen Wert ändern.

Zweitens sollte der Inhalt dieses trashed Array Ihnen einen Hinweis geben, woher dieses Material kam! Es scheint ein Fragment von Text zu sein, das auf Ihre Eingabe zurückverfolgt werden kann, und von dort aus können Sie verfolgen, wo dieser Teil der Eingabe in Ihrem Parsing-Rechner behandelt wird.

+0

Ich verstehe das Problem jetzt. Ich werde versuchen, es zu korrigieren. Ich habe irgendwie die Größe der Saiten reduziert und es funktionierte, aber ich werde es auf Ihre Weise debuggen. ich danke dir sehr :) – YuNo

0

Versuchen mit

tmp_idList = malloc(strlen(id) +1) 

auch C++ String Klasse statt char * Ich schlage vor, Sie verwenden. Es ist anfälliger für Fehler für Anfänger, die C-Zeiger und Speicherzuweisung (die aussieht wie Sie) nicht vollständig verstehen.

+0

Nein, es funktioniert nicht. Es ist eine inkompatible Aufgabe. – YuNo

+0

ich glaube nicht, ich kann C++ - Zeichenfolgen verwenden, weil Bison eine c-Datei generiert – YuNo

Verwandte Themen