我写了一个函数来读取带有 fgets 的字符串,它使用 realloc() 使缓冲区在需要时增长:
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 说:
(...) ==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... 它确认传递的 arg 的值为 -48。 我不知道单独启动和使用 valgrind 时程序的运行方式不同。我的代码有问题还是只是 valgrind 错误?
最佳答案
当您重新分配缓冲区时,您的指针“p”仍指向旧缓冲区。
这会占用内存,还会导致 future 的分配使用虚假值。
关于c - 使用 realloc 的程序在 Valgrind 中表现不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13791993/