2016-08-10 5 views
-1

Я скомпилировал код на своем Mac с флагом оптимизации GCC -O3, чтобы ускорить время выполнения. Это отлично работает на моей локальной машине и приводит к увеличению скорости на 2/3.GCC Оптимизация: ошибка, вызванная fgets

Однако я попытался скомпилировать код на Amazon EC2, так как я имею дело с большим набором данных. Использование флага оптимизации -O3 вызывает следующее предупреждение

предупреждения: призыв к «__fgets_chk_warn» объявлено с предупреждением атрибута: fgets вызывается с большим размером, чем длина буфера назначения

В соответствующей функции, текстовый файл анализируется по строкам. Тем не менее, я не совсем понимаю, почему я получаю предупреждение. Код функции выглядит следующим образом:

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 является указателем на массив с 10000 элементов по умолчанию. Количество записей неизвестно заранее, но возвращается функцией.

+8

'40 <80'. Не кажется слишком загадочным. – EOF

+0

Проблема в том, что строка представляет собой массив из 40 байт, но вы говорите, что у него 80 байт. Используйте sizeof (line) вместо 80. –

+0

Давайте продолжим предупреждение: 'fgets вызывается с большим размером (что составляет 80), чем длина буфера назначения (что равно 40)' – alk

ответ

3

Вы действительно вызываете fgets(line, 80, fp), но целевой массив line определяется как массив из 40 char. Компилятор на Amazon EC2 лучше настроен или умнее вашего. Это реальная ошибка, если файл содержит строки длиной более 39 байт.

Кстати, компилятор, вызываемый как gcc на Mac, обычно является экземпляром clang. Попробуйте gcc --version.

Обратите внимание, что ваша программа не проверяет, читается ли слишком много данных, и если преобразование sscanf() преуспевает. Оба они приводят к неопределенному поведению.

Вот безопасный вариант:

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 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^