3 Stimmen

SIGABRT bei fclose?

Ich habe Schwierigkeiten, einige C-Code korrekt ausführen (bitte haben Sie Verständnis, wenn diese Frage dumm ist, da ich neu in C bin; außerdem, damit jeder klar ist, ist dies Code, den ich Probleme beim Ausführen habe. Der einzige Teil, den ich geschrieben habe, ist die Null-Filehandle-Prüfung). Im Grunde stürzt mein Programm ab bei fclose . Code first:

Am Anfang der Datei:

int *label;

Methodenspezifisch:

void load_dat ()
{
  int    i, j, t, k;
  FILE   *in;
  char   t_file[16];

  printf ("\nName of Raw Data File > ");
  scanf ("%s", t_file);
  in = fopen (t_file, "r");
  if (in == NULL){
    perror("fopen error");
  }
 fscanf (in, "%d %d %d", &num_pats, &a_length, &b_length);

 dpt = (float **) malloc (sizeof(float *)*num_pats);

 for (k=0; k<num_pats; k++){
    dpt[k] = (float *) malloc (sizeof(float)*(a_length+b_length));
 }

 label = (int *) malloc (sizeof(int)*num_pats);

  for (i=0; i<num_pats; i++)
  {
      for (j=0; j<a_length; j++)
      {
        fscanf (in, "%f", &dpt[i][j]);
      }

  fscanf (in, "%d", &label[i]);

  if (label[i]<0 || label[i]>3)
    printf ("ERROR: Label corrupted.\n");

    for (t=0; t<b_length; t++){
        dpt[i][t+a_length] = 0.0;
        dpt[i][label[i]+a_length] = 1.0;
    }
  }
  fclose (in); 
}      

Meine Fehlermeldung des Programms lautet: Abort trap: 6 . Das Googeln nach diesem Thema führte schließlich zu dem Vorschlag, dass ich die GBD die mir gegeben wurde:

Program received signal SIGABRT, Aborted.

Und

#0  0x00007fff8c12582a in __kill ()
#1  0x00007fff871a3b6c in __abort ()  
#2  0x00007fff871a0070 in __stack_chk_fail ()
#3  0x000000010000175f in load_dat ()
#4  0x0000000100001baa in main ()
#5  0x00000001000013e4 in start ()

Wenn ich die gesamte Methode durchlaufe, stürzt das Programm nicht ab, bis ich die letzte Zeile erreiche fclose(in) . Auch der Wert für in bleibt während des gesamten Programms gleich.

Suche nach Problemen mit fclose stieß ich auf dieser SO-Posten was mich dazu veranlasst hat, die Verwendung von Valgrind , dessen Ausgabe (unter Verwendung von --leak-check=yes ) ist:

==22688== 
==22688== Process terminating with default action of signal 6 (SIGABRT)
==22688==    at 0x2DD82A: __kill (in /usr/lib/system/libsystem_kernel.dylib)
==22688==    by 0x18A06F: __stack_chk_fail (in /usr/lib/system/libsystem_c.dylib)
==22688==    by 0x10000175E: load_dat (in ./dataPre) 
==22688==    by 0x100001BA9: main (in ./dataPre)
==22688== 
==22688== HEAP SUMMARY:
==22688==     in use at exit: 28,781 bytes in 83 blocks
==22688==   total heap usage: 84 allocs, 1 frees, 32,877 bytes allocated
==22688== 
==22688== LEAK SUMMARY:
==22688==    definitely lost: 0 bytes in 0 blocks
==22688==    indirectly lost: 0 bytes in 0 blocks
==22688==      possibly lost: 0 bytes in 0 blocks
==22688==    still reachable: 28,781 bytes in 83 blocks
==22688==         suppressed: 0 bytes in 0 blocks
==22688== Reachable blocks (those to which a pointer was found) are not shown.
==22688== To see them, rerun with: --leak-check=full --show-reachable=yes
==22688== 
==22688== For counts of detected and suppressed errors, rerun with: -v
==22688== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Abort trap: 6

Jetzt weiß ich nicht mehr, wo ich suchen oder was ich tun soll.

Beispielhafte Daten:

44  96  3                                                                                                                                                                                                                                                                                                                                                                                       
0   0   17.57298681 24.18012088 0   24.07599728 0   0   0   19.53417371 22.61467731 15.5650829  18.65720893 21.70631048 26.8811321  23.88086356 23.73544942 0   0   22.63088094 21.11777268 22.06847477 22.38688445 19.6794802  20.95594497 22.56472976 15.5058779  0   16.89366861 21.23974633 0   19.01608872 22.58492673 22.39564384 18.17000387 0   0   25.85404904 23.80483437 22.64271243 0   17.09819014 24.60634479 0   24.74696139 29.27117194 20.8931952  19.08648917 23.95167438 0   0   17.2386599  0   0   23.22304254 22.86712074 0   21.45687449 21.45146304 0   0   0   20.98717232 0   18.09871479 17.8226754  23.72508288 23.34563846 21.26201041 17.44038043 22.49848573 18.99848797 16.43222002 14.8132735  22.28093734 17.78931496 0   20.46914933 17.87742323 21.07936723 23.52102135 0   17.90498094 21.93199281 0   0   16.3020812  0   18.17972854 16.43234906 19.0756696  0   0   22.98048214 23.22184013 21.54024161 0

Beachten Sie, dass num_pats bezieht sich auf die Zahlenreihen, a_length auf die Anzahl der Spalten. b_length ist die Anzahl der verschiedenen Eingabearten (die letzte Zahl jeder Zeile). In meiner Beispieldatei gibt es 44 Zeilen.

4voto

Wie groß ist der String, der in t_file geladen wird? Sie weisen dort nur 16 Bytes zu...

0voto

caruizdiaz Punkte 163

Sie führen keine Validierung über "num_pats" durch.

Wenn fscanf aus irgendeinem Grund fehlschlägt, kann num_pats gleich Null oder ein negativer Wert sein, was zu einem Abbruch führt.

0voto

wallyk Punkte 55322

Mit ziemlicher Sicherheit wird das Problem durch das Schreiben in nicht zugewiesenen Speicher verursacht. Die Operationen mit FILE *in sehen gut aus.

Die Verwaltung des dynamischen Speichers ist jedoch ziemlich komplex (selbst für einen Anfänger ist dies ein komplexer Code, selbst für fortgeschrittene C-Programmierer). Da es keine Validierungsprüfungen für fehlgeschlagene Zuweisungen und die Gültigkeit von Eingaben gibt, ist wahrscheinlich eine dieser Zuweisungen das Abschreiben des Endes einer Zuweisung: entweder ist die Zuweisung nicht groß genug, oder die Art und Weise, wie sie dereferenziert wird, stimmt nicht mit der ursprünglichen Zuweisung überein, ein Problem bei der Verwendung von Casts. Ein solcher Schreibvorgang zerstört offensichtlich etwas in FILE *in was zu fclose() zum Absturz bringen, wenn es schließlich aufgerufen wird. Das Problem tritt lange vor dem fclose() Allerdings.

Wenn Sie Beispieleingabedaten beifügen, die zum Absturz führen, sollte es für mich offensichtlich sein, was falsch läuft.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X