首先,我知道有人问过类似的问题。但是,我想提出一个更普遍的简单问题,涉及真正原始的 C 数据类型。所以就在这里。
在 main.c
中,我调用一个函数来填充这些字符串:
int
main (int argc, char *argv[]){
char *host = NULL ;
char *database ;
char *collection_name;
char *filename = "";
char *fields = NULL;
char *query = NULL;
...
get_options(argc, argv, &host, &database, &collection_name, &filename,
&fields, &query, &aggregation);
在 get_options
中:
if (*filename == NULL ) {
*filename = (char*)realloc(*filename, strlen(*collection_name)*sizeof(char)+4);
strcpy(*filename, *collection_name);
strcat(*filename, ".tde"); # line 69
}
我的程序运行良好,但随后 Valgrind 告诉我我做错了:
==8608== Memcheck, a memory error detector
==8608== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==8608== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==8608== Command: ./coll2tde -h localhost -d test -c test
==8608==
==8608== Invalid write of size 1
==8608== at 0x403BE2: get_options (coll2tde.c:69)
==8608== by 0x402213: main (coll2tde.c:92)
==8608== Address 0xa2edd18 is 0 bytes after a block of size 8 alloc'd
==8608== at 0x4C28BED: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8608== by 0x4C28D6F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8608== by 0x403BBC: get_options (coll2tde.c:67)
==8608== by 0x402213: main (coll2tde.c:92)
你能解释一下错误吗 Address 0xa2edd18 is 0 bytes after a block of size 8 alloc'd
?
我该如何解决这个问题?
最佳答案
strcpy
添加一个空终止符 '\0'
。你忘了为它分配空间:
*filename = (char*)realloc(*filename, strlen(*collection_name)*sizeof(char)+5);
您需要为 5 个字符添加空格:4 个用于 ".tde"
后缀,另外一个用于 '\0'
终止符。您当前的代码仅分配 4 个,因此最后一次写入是在您为新文件名分配的 block 之后的空间中完成的(即它之后的 0 个字节)。
注意:您的代码有一个常见问题 - 它将 realloc
的结果直接分配给正在重新分配的指针。当 realloc
成功时这很好,但失败时会造成内存泄漏。修复此错误需要将 realloc
的结果存储在一个单独的变量中,并在将值赋回给 *filename
之前检查它是否为 NULL
:
char *tmp = (char*)realloc(*filename, strlen(*collection_name)*sizeof(char)+5);
if (tmp != NULL) {
*filename = tmp;
} else {
// Do something about the failed allocation
}
直接分配给 *filename
会造成内存泄漏,因为 *filename
指向下方的指针会在失败时被覆盖,变得不可恢复。
关于c - valgrind - 地址 ---- 在分配大小为 8 的 block 之后为 0 字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27636306/