Frage

Ich arbeite Schwanz für eine Zuordnung zu implementieren. Ich habe es richtig funktioniert aber ich frei zu zufälligen Zeiten ein Fehler zu sein scheinen zu bekommen.

Ich kann nicht sehen, es auf der Spur zu einem Muster oder etwas anderes als es konsistent ist.

Zum Beispiel, wenn ich mein Programm als „tail -24 test.in“ nenne, würde ich die die die falschen Prüfsumme Fehler bei der gleichen Linie auf mehreren Läufe erhalten. Jedoch mit unterschiedlichen Dateien und sogar eine unterschiedliche Anzahl von Zeilen, die ich ohne Fehler kommen wieder zu drucken zurück.

Jede Idee, wie das Problem auf die Spur, ich habe es stundenlang versucht, ohne Erfolg zu debuggen.

Hier ist der säumige Code:

Linien als Zeichen definiert ** und waren malloc wie:

lines = (char**) malloc(nlines * sizeof(char *));

void insert_line(char *s, int len){

  printf("\t\tLine Number: %d Putting a %d line into slot: %d\n",processed,len,slot);
  if(processed > numlines -1){//clean up
    free(*(lines+slot));
    *(lines + slot) = NULL;
  }
  *(lines + slot) = (char *) malloc(len * sizeof(char));
  if(*(lines + slot) == NULL) exit(EXIT_FAILURE);
  strcpy(*(lines+slot),s);
  slot = ++processed % numlines;
}
War es hilfreich?

Lösung

Ihre Routine wird über die zugewiesenen Zeilenpuffer zu schreiben.

Die Größe der Zeile als Argument übergeben (das heißt „len“) wahrscheinlich auch nicht die NUL Terminator. Wenn Sie malloc rufen Sie die Zeile (das heißt „s“) Sie ein zusätzliches Byte für den String-Terminator zuweisen müssen kopieren:

 *(lines + slot) = (char *) malloc((len + 1) * sizeof(char));

Andere Tipps

Wenn Sie konsequent das Problem mit bestimmtem Eingabeparameter wiedergeben können, sollten Sie wie folgt debuggen:

  • Erste Debug auf den genauen frei, die das Problem verursacht.
  • Dann herauszufinden, wann der Speicher, der im Begriff ist, zu free'd wurde malloc'ed.
  • Als nächstes Debug an den Ort, wo der Speicher malloc'ed wird.
  • Suchen Sie den zugewiesenen Speicherblock in dem Speicher-Viewer. Beachten Sie sowohl den Beginn und das Ende des Blocks. Es gibt wohl einen besonderen Wert a Wache Block kurz vor und kurz nach dem Block.
  • genannt
  • Geben Sie nun Schritt durch den Code, bis der Speicher free'd wird. An einem gewissen Punkt sollte Ihr Code fälschlicherweise den Schutzblock überschreibt. Das ist die säumige Anweisung.

Beachten Sie, dass das Problem sehr gut in einem ganz anderen Teil des Programms sein könnte. Auch wenn es diese frei ist, die den Fehler meldet, wird der Code, der die Wache Block überschreibt kann überall sein.

Meine erste Frage ist, wie Sie len berechnen? Ist es Strlen gerade oder hat es Platz für den \ 0-Terminator zu enthalten? Ich glaube, Sie können Ihre Zuordnung in Ihrem strcpy werden überschieß. Bad Verhalten neigt dazu, auf Wortgrenzen passieren und zufällig erscheinen. Überprüfen Sie auch, um sicherzustellen, dass Ihre Quellstrings sind null beendet. Wenn Sie einen Fehler auf der Leseseite gemacht und haben sie nicht beenden. Dann kann strcpy zufällig Dinge zu überschreiben werden.

  *(lines + slot) = (char *) malloc(len * sizeof(char));
  if(*(lines + slot) == NULL) exit(EXIT_FAILURE);
  strcpy(*(lines+slot),s);

Vielleicht versuchen:

  lines[slot] = (char *) malloc((len + 1) * sizeof(char));
  if(lines[slot] == NULL) exit(EXIT_FAILURE);
  if(strlen(s) <= len){
    strcpy(lines[slot],s);
  }
  else{
    /* do something else... */
  }

Im Hinblick auf die allgemeine Form, ich möchte auch Sie ermutigen, einige stilistische Änderungen zu machen das Ganze etwas besser lesbar zu machen, einfacher zu folgen und beständig gegen Fehler.

Pointer-Arithmetik ist gültig und Spaß, aber ich denke, Ihre Absicht, ein wenig mehr klar ist, ob Sie die Array-Form wie verwenden:

free(lines[slot]);
lines[slot] = NULL;

statt

free(*(lines+slot));
*(lines + slot) = NULL;

Ich würde empfehlen Sie, auch weniger Statik zu verwenden. Es ist leicht genug, um sie in einer Datenstruktur durch und sie um in der Zugriffs- und Mutatoren passieren. Es wird viel mehr klar, wo die Aktion geschieht verhindert, dass Sie tun Dinge wie:

static int numlines = 0;
void insert_line(char *s, int len){
    int numlines = 5;

, wo Sie Scoping Probleme vorstellen können, die nur unglücklich sind, zu debuggen.

Haben nlines und numlines den gleichen Wert haben?

Hat der Anrufer von insert_line läßt Raum für die Hinter NUL wenn die Länge in dem zweiten Parameter übergeben?

Ich bin mir nicht sicher, dass es in engen Zusammenhang steht, aber diese beiden Linien scheinen verdächtig zu mir:

  *(lines + slot) = (char *) malloc(len * sizeof(char));
  if((lines + slot) == NULL) exit(EXIT_FAILURE);

Sie zuerst die Rückkehr von malloc zuweisen lines[slot] und dann (lines+slot) Sie überprüfen, wenn dieser NULL war, Sie dereferenzieren einen NULL-Zeiger hatte!

Auch wenn Linien [Slot] (Ihre * (Linien + Slot)) nicht null ist, werden Sie ein Speicherleck auf, wenn Sie das Ergebnis von malloc (), um es zuzuweisen.

Ich gehe davon aus lines ein char ist * Linien [] `und Schlitz ist innerhalb der erlaubten Grenze!

Ich bin damit einverstanden Verdacht mit Remos über diese beiden Linien, nicht aber die Tangente, die auf ging Remo entfernt. Wir sollten Kredit für die Suche nach diesen Fehlern teilen.

*(lines + slot) = some value
if((lines + slot) == NULL) then die
should be
if(*(lines + slot) == NULL) then die
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top