我寫了一個函數來讀取用於fgets一個字符串使用realloc的(),使在需要時緩衝成長:計劃與realloc的行爲不同Valgrind的
char * read_string(char * message){
printf("%s", message);
size_t buffsize = MIN_BUFFER;
char *buffer = malloc(buffsize);
if (buffer == NULL) return NULL;
char *p;
for(p = buffer ; (*p = getchar()) != '\n' && *p != EOF ; ++p)
if (p - buffer == buffsize - 1) {
buffer = realloc(buffer, buffsize *= 2) ;
if (buffer == NULL) return NULL;
}
*p = 0;
p = malloc(p - buffer + 1);
if (p == NULL) return NULL;
strcpy(p, buffer);
free(buffer);
return p;
}
我編譯的程序,並試了一下,它按預期工作。但是,當我用Valgrind的運行它,當讀字符串> = MIN_BUFFER和Valgrind的說,函數返回NULL:
(...) ==18076== Invalid write of size 1 ==18076== at 0x8048895: read_string (programme.c:73) ==18076== by 0x804898E: main (programme.c:96) ==18076== Address 0x41fc02f is 0 bytes after a block of size 7 free'd ==18076== at 0x402BC70: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==18076== by 0x8048860: read_string (programme.c:76) (...) ==18076== Warning: silly arg (-48) to malloc() (...)
我加* p = 0時之間的printf語句;並且p = malloc ...並且它確認參數傳遞的值是-48。 我不知道單獨和valgrind啓動時,程序不會運行相同的方式。我的代碼中是否有錯誤,或者它只是一個valgrind錯誤?
Sidenote:如果realloc()返回NULL,你的代碼會泄漏內存 - 在這種情況下,在返回NULL之前使用臨時變量並釋放前一個指針。 – 2012-12-09 21:27:32
'* p = 0;'可以寫出一個超出分配的大小。 – wildplasser