2016-03-15 159 views
1

昨天我问了一个问题,以便您可以帮助我调试一个基本上由标准输入读取可变长度行的程序。过了一段时间我以为我已经解决了所有问题,但今天,valgrind仍在抱怨。Valgrind - 1个块中的2,064个字节可能丢失64个损失记录中的57个

我编译我的程序有:

gcc -g -o find_all_words find_all_words.c 

,然后我用的valgrind如下:

valgrind --leak-check=full --show-leak-kinds=all ./find_all_words hello world 

它也指出在while环路我的代码另一部分:

==15333== Memcheck, a memory error detector 
==15333== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==15333== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info 
==15333== Command: ./find_all_words hello world 
==15333== 
Enter your favourite citation: hello world, how are you today? 
line = hello world, how are you today? 
Input arguments: 
1 = hello 
2 = world 
==15333== 
==15333== HEAP SUMMARY: 
==15333==  in use at exit: 30,666 bytes in 189 blocks 
==15333== total heap usage: 276 allocs, 87 frees, 36,976 bytes allocated 
==15333== 
==15333== 2,064 bytes in 1 blocks are possibly lost in loss record 57 of 64 
==15333== at 0x100009104: malloc_zone_malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==15333== by 0x1004F4EFD: _objc_copyClassNamesForImage (in /usr/lib/libobjc.A.dylib) 
==15333== by 0x1004E8182: protocols() (in /usr/lib/libobjc.A.dylib) 
==15333== by 0x1004E8093: readClass(objc_class*, bool, bool) (in /usr/lib/libobjc.A.dylib) 
==15333== by 0x1004E5C13: gc_init (in /usr/lib/libobjc.A.dylib) 
==15333== by 0x1004ED24E: objc_initializeClassPair_internal(objc_class*, char const*, objc_class*, objc_class*) (in /usr/lib/libobjc.A.dylib) 
==15333== by 0x1004FA132: layout_string_create (in /usr/lib/libobjc.A.dylib) 
==15333== by 0x1004E883C: realizeClass(objc_class*) (in /usr/lib/libobjc.A.dylib) 
==15333== by 0x1004E8300: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib) 
==15333== by 0x1004E82E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib) 
==15333== by 0x1004E82E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib) 
==15333== by 0x1004E82E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib) 
==15333== 
==15333== 4,096 bytes in 1 blocks are still reachable in loss record 63 of 64 
==15333== at 0x100008E3B: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==15333== by 0x1001E2AF5: __smakebuf (in /usr/lib/system/libsystem_c.dylib) 
==15333== by 0x1001E66D0: __srefill0 (in /usr/lib/system/libsystem_c.dylib) 
==15333== by 0x1001E67B8: __srefill (in /usr/lib/system/libsystem_c.dylib) 
==15333== by 0x1001DFA66: fgets (in /usr/lib/system/libsystem_c.dylib) 
==15333== by 0x100000A73: readline (find_all_words.c:26) 
==15333== by 0x100000E0D: main (find_all_words.c:94) 
==15333== 
==15333== LEAK SUMMARY: 
==15333== definitely lost: 0 bytes in 0 blocks 
==15333== indirectly lost: 0 bytes in 0 blocks 
==15333==  possibly lost: 2,064 bytes in 1 blocks 
==15333== still reachable: 4,096 bytes in 1 blocks 
==15333==   suppressed: 24,506 bytes in 187 blocks 
==15333== 
==15333== For counts of detected and suppressed errors, rerun with: -v 
==15333== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from 17) 

这是我的程序:

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 

/** 
* Gets and a variable-size line from the standard input. 
*/ 
char * readline(){ 

    size_t n = 10; 
    char* final = calloc(n, sizeof(char)); 
    final[0] = '\0'; 
    char* tmp; // used for allocating memory temporarily 

    // constant buffer size used to store the read characters 
    // before storing them in the final buffer 
    char buf[10]; 

    while(fgets(buf, sizeof buf, stdin) != NULL) { 

     if(buf[strlen(buf) - 1] == '\n') { 

      if(strlen(buf) > 1) { 

       if((n - strlen(final)) < (strlen(buf) + 1)) { 
        // -1 because buf contains also \n at the end 
        n = strlen(final) + strlen(buf); 
        tmp = calloc(n, sizeof(char)); 

        for(int i=0; i <= strlen(final); ++i) 
         tmp[i] = final[i]; 

        free(final); 

       } else { 
        tmp = final; 
       } 

       int i, j; 
       for(i = strlen(tmp), j = 0; j <= (strlen(buf) - 2); ++i, ++j) 
        tmp[i] = buf[j]; 

       tmp[i] = '\0'; 
       final = tmp; 
       tmp = NULL; 
      } 

      break; 

     } else { // no newline inserted at the end 

      if((n - strlen(final)) < (strlen(buf) + 1)) { 
       n *= 2; 
       tmp = calloc(n, sizeof(char)); 

       for(int i = 0; i <= strlen(final); ++i) 
        tmp[i] = final[i]; 

       free(final); 

      } else { 
       tmp = final; 
      }  

      // Starts inserting from the '\0' char 
      // Insert also the '\0' at the end 
      for(int i = strlen(tmp), j = 0; j <= 9; ++i, ++j) 
       tmp[i] = buf[j]; 

      final = tmp; 
      tmp = NULL; 
     } 
    } 

    return final; 
} 


int main(int argc, char *argv[]){ 
    if(argc < 2){ 
     fprintf(stderr, "usage: at least one string as command-line argument.\n"); 
     exit(1); 
    } else { 

     printf("Enter your favourite citation: "); 

     char *line = readline(); 

     printf("line = %s\n", line); 

     printf("Input arguments:\n"); 

     for(int i=1; i < argc; ++i) 
      printf("%i = %s\n", i, argv[i]); 

     free(line); 
    } 



    return 0; 
} 

感谢您的帮助!

+0

奇数。我测试你的代码的方式与你所做的一样(添加必要的内容),而valgrind并不抱怨。什么是第26行? –

+0

@JulienLopez这是while循环... – nbro

+0

然后你可以发布你的完整程序吗?根据你的valgrind输出,有几行缺失。 –

回答