2016-08-10 4 views
-1

Ich kompilierte Code auf meinem Mac mit dem GCC Optimization Flag -O3 an, um die Ausführungszeit zu beschleunigen. Dies funktionierte perfekt auf meiner lokalen Maschine und führte zu einer Geschwindigkeitssteigerung um 2/3.GCC-Optimierung: Fehler verursacht durch fgets

Allerdings habe ich versucht, den Code auf dem Amazon EC2 zu kompilieren, da es sich um einen großen Datensatz handelt. die -O3 Optimierung Flag verwendet, verursacht die folgende Warnung

Warnung: Aufruf zu ‚__fgets_chk_warn‘ mit dem Attribute Warnung erklärt: fgets mit größerer Größe als die Länge des Zielpuffers

In der jeweiligen Funktion aufgerufen, ein Textdatei wird zeilenweise analysiert. Allerdings verstehe ich nicht wirklich, warum ich die Warnung habe. Der Code der Funktion lautet wie folgt:

int loadPriceData(const char *filename, double *target) { 
    char line[40]; 
    FILE *fp; 
    fp = fopen(filename, "r"); 
    if (fp == NULL) { 
     return -1; 
    } 
    int i = 0; 
    while (fgets(line, 80, fp) != NULL) { 
     sscanf(line, "%lf\n", target + i); 
     i += 1; 
    } 
    fclose(fp); 
    return i; // Return number of elements 
} 

target ist ein Zeiger auf ein Array mit Elementen 10000 standardmäßig. Die Anzahl der Einträge ist nicht im Voraus bekannt, wird aber von der Funktion zurückgegeben.

+8

'40 <80'. Scheint nicht zu kryptisch. – EOF

+0

Das Problem ist, dass Zeile ein Array von 40 Bytes ist, aber Sie teilen Bünden, dass es 80 Bytes hat. Verwenden Sie sizeof (line) anstelle von 80. –

+0

Lassen Sie uns die Warnung erweitern: 'fgets mit größerer Größe (die 80) als die Länge des Zielpuffers (das ist 40) genannt' – alk

Antwort

3

Sie rufen tatsächlich fgets(line, 80, fp), aber das Ziel-Array line ist als ein Array von 40 Char definiert. Der Compiler auf dem Amazon EC2 ist besser konfiguriert oder intelligenter als deins. Dies ist ein echter Fehler, wenn die Datei Zeilen enthält, die länger als 39 Byte sind.

Übrigens ist der Compiler aufgerufen als gcc auf dem Mac in der Regel eine Instanz von clang. Versuchen Sie gcc --version.

Beachten Sie, dass Ihr Programm nicht überprüft, ob zu viele Daten gelesen werden, oder ob die sscanf() Konvertierung erfolgreich ist. Beides führt zu undefiniertem Verhalten. Hier

ist eine sicherere Version:

int loadPriceData(const char *filename, double *target, int nb_items) { 
    char line[80]; 
    FILE *fp = fopen(filename, "r"); 
    if (fp == NULL) { 
     return -1; 
    } 
    int i = 0; 
    while (fgets(line, sizeof line, fp) != NULL) { 
     if (i < nb_items) { 
      if (sscanf(line, "%lf", target + i) != 1) 
       target[i] = 0; 
     } 
     i += 1; 
    } 
    fclose(fp); 
    return i; // Return number of elements 
} 
Verwandte Themen