2015-03-24 1 views
0

Valgrind делает эти жалобыНеужели valgrind жалуется на неинициализированные переменные, которые я инициализировал?

Conditional jump or move depends on uninitialised value(s) 
==8443== at 0x40070F: main (test.c:31) 
==8443== Uninitialised value was created by a heap allocation 
==8443== at 0x4C29BCF: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) 
==8443== by 0x4EA4847: getdelim (in /usr/lib64/libc-2.20.so) 
==8443== by 0x40079E: main (test.c:24) 

Линия 31 относится к линии ниже if(line[i] == '(' || line[i] == '{' || line[i] == '[') и линия 24 относится к линии ниже while (getline(&line, &len, fp) != -1) {.

int main(){ 
    FILE * fp; 
    char * line = NULL; 
    size_t len = 0; 
    fp = fopen("test.json", "r"); 
    if (fp == NULL) 
     return 0; 

    while (getline(&line, &len, fp) != -1) { 
     if(!line) 
      break; 
     int i; 

     // Go through each letter 
     for(i = 0; i<len; i++){ 
      if(line[i] == '(' || line[i] == '{' || line[i] == '[') 
       printf("%c",line[i]); 

     }  
     if(line) 
      free(line); 
     line = NULL; 
     len = 0; 
    } 

    fclose(fp); 
    if (line) 
     free(line); 
    return 1; 
} 

Я сделал некоторый поиск других вопросов с подобными проблемами, которые заставили меня попытаться освободить линию в конце цикла в то время как и Реинициализация двух переменных, но я получаю эту жалобу и может Подумайте, почему.

Что я делаю неправильно?

ответ

0

Проблема заключается в том, как вы используете getline().

От: страница руководства

«... на успешном вызове, * lineptr и * п будет обновляться, чтобы отражать адрес буфера и выделяется размер соответственно.»

«При успешном завершении getline() и getdelim() возвращают количество прочитанных символов, включая символ разделителя, но не включая завершающий нулевой байт ('\ 0')."

Это не означает, что выделенная сумма будет точно соответствовать количеству прочитанных байтов ... фактически, в моей системе выделенный буфер всегда будет составлять не менее 120 байт, независимо от того, сколько символов считывается в Это. Я считаю, что это по соображениям производительности - и что getline() будет перерабатывать буфер, если он достаточно большой, до realloc(), когда это не так. Кроме того, поскольку getline() может повторно использовать один и тот же буфер при повторных вызовах (и перераспределяет буфер, если он слишком мал для вас), ваш код будет работать лучше, если вы не освободите line до последнего getline().

Чтобы исправить код, вы будете делать что-то вроде этого:

int main(void) 
{ 
    FILE *fp; 
    char *line = NULL; 
    size_t len=0; 
    ssize_t bytesread; 
    int i,j=1; 

    fp = fopen("test.json", "r"); 
    if (fp == NULL) 
     return 0; 

    while ((bytesread=getline(&line, &len, fp)) != -1) 
    { 
     // This demonstrates the point: 
     printf("line %3d len: %d bytesread: %d\n", j++, len, bytesread); 

     if (!line) 
     break; 

     // Go through each letter 
     for (i = 0; i < bytesread; i++) { 
     if(line[i] == '(' || line[i] == '{' || line[i] == '[') 
      printf("%c", line[i]); 
     } 
    } 

    fclose(fp); 
    free(line); 
    return 0; // traditionally in C, 0 means success. 
      // if you include stdlib.h, you could use the EXIT_SUCCESS macro. 
} 
Смежные вопросы