昨天我问了一个问题,这样你就可以帮我调试一个程序,该程序主要包括从标准输入读取一个可变大小的行。过了一会儿,我以为我已经解决了所有问题,但今天,valgrind还在抱怨。
我编写了我的程序:
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 :(得分:4)
在这里查看:Possible Memory Leak Valgrind in OSX El Capitan和此处:Valgrind Errors on Mac OS X for printf a double。
然后你可以安全地忽略valgrind中的那些错误。 :)