2012-04-13 8 views
1

Ich kopierte etwas Code, der einfach liest eine Datei in eine Zeichenfolge und druckt die Zeichenfolge aus einem älteren Programm. Es hat gut funktioniert, also habe ich beschlossen, es etwas zu ändern. Das neue Programm istZuordnung zu Variable gibt Segmentierung Fehler in völlig unabhängig Funktion

#include <stdio.h> 
#include <string.h> 

int main() { 
    FILE *itemlist = fopen("itemlist", "r"); 
    char *currentstring, charbuffer[2]; 
    // char itemstart = 0; 
    while (fgets(charbuffer, 2, itemlist)) { 
     strcat(currentstring, charbuffer); 
    } 
    printf("%s", currentstring); 
    return 0; 
} 

Und es funktioniert wie erwartet. Aber wenn ich die itemstart Zeile auskommentiere, gibt es einen Segmentierungsfehler. Ich benutze es nicht einmal und für mich ist es nicht illegal, einen Char auf 0 zu initialisieren. Ich dachte, es wäre ein Problem mit Typen, dann änderte ich es in einen kurzen und dann in int und es gab immer noch einen segfault.

Aber dann habe ich den = 0 Teil entfernt und es hat wieder funktioniert. Dann entschied ich mich, es zurückzusetzen, die Binärdatei mit gdb zu debuggen, und der segfault war bei strcat.

Wie ist das möglich?

+0

Worauf deutet "Stringstring" hin? – geekosaur

+0

Nichts im Moment, es ist nur eine leere Saite. Wenn ich "Stringstring" auf NULL setze, segmentiert es. – user1002327

+2

Das war rhetorisch. Du hast recht, es zeigt auf * nichts *. Zufallsspeicher Was denkst du passiert, wenn du zufälligen Speicher modifizierst? Wo glaubst du, dass es darauf hindeuten würde, dass du nur zufällig darauf schreiben könntest? – geekosaur

Antwort

4

currentstring ist ein dangling Zeiger, so strcat(currentstring, charbuffer); führt zu undefiniertem Verhalten.

Wahrscheinlich wird char itemstart = 0char itemstart = 0 initialisiert einige Speicher auf 0 und die Zugriffsverletzung wird sichtbar gemacht, jedoch ist dies nur eine Vermutung. Undefiniertes Verhalten bedeutet, dass alles passieren kann.

Sie sollten Speicher für currentstring zuweisen:

currentstring = malloc(10); //or whatever length you need 
+0

Sie haben seinen Code korrigiert, aber Sie haben seine Frage nicht beantwortet :) –

+0

Dies wird ein Programm sein, das eine Artikelliste mit dem Format 'id = [Name, Eigenschaften, ...]' liest, also die Länge jeder Zeile könnte 10 oder 150 sein. – user1002327

+0

@EdritchConundrum Ich habe. Undefiniertes Verhalten Lesen Sie die Antwort erneut. –

1

Sie müssen etwas Platz für Stringstring reservieren.

1

Segfaults wenn uncommenting unabhängige Linien durch die unsafeness der Sprache C möglich gemacht werden. Das Endeverhalten eines falschen Programms wird durch subtile Entscheidungen des Compilers bestimmt.

Wenn Sie mit solch einem Wahnsinn konfrontiert werden, sollten Sie zuerst versuchen, Ihren Code zu korrigieren. Das ist natürlich nicht immer einfach. In einem 8-Zeilen-Programm sollten Sie jedoch in Ordnung sein.

1

Sie müssen Speicherplatz für currentstring Variable zuweisen und die Größe davon steuern, um Segmentfehler/Heap-Beschädigung zu vermeiden.

#define MAX_BUFFER_SIZE 32 
//... 
FILE *itemlist = fopen("itemlist", "r"); 
char *currentstring = malloc(MAX_BUFFER_SIZE+1); 
char *tmpbuf; 
char charbuffer[2]; 
// char itemstart = 0; 
int bytesloaded = 0; 
while (fgets(charbuffer, 2, itemlist)) { 

    if(bytesloaded + 2 > buf_size) { 
     /* call realloc() */ 
     buf_size += MAX_BUFFER_SIZE; 
     tmpbuf = realloc(currentstring, buf_size); 
     if(tmpbuf == NULL) { /* Get off loop. Using break or return. */ 
      break; 
     } 
     currentstrig = tmpbuf; 
    } 
    memcpy(currentstring + bytesloaded, charbuffer, 2); 
    bytesloaded += 2; 
} 
//... 
free(currentstring); 

Ich habe nicht getestet, aber ich glaube, dass es funktioniert.