我有一个程序将字符读入动态字符串缓冲区。我们不知道字符串的大小,并且要求我们不要简单地设置固定大小的“足够大”的缓冲区。
相关功能的工作方式如下:
char* read_field(FILE* data)
{
int size = 8;
char *field = malloc(size);
if (field == NULL)
exit(1);
char *tmp = NULL;
int idx = 0;
int ch = EOF;
while (ch) {
ch = fgetc(data);
// Double size if full
if (size <= idx) {
size *= 2;
tmp = realloc(field, size);
if (!tmp)
exit(1);
field = tmp;
}
field[idx++] = ch;
// Relevant termination in my use case
if (ch == ';' || ch == '\n')
ch = 0;
}
printf("field: %s\n"); // value correct, but sometimes valgrind error
return field; // field is free'd by the caller
}
现在该程序似乎工作,但当通过Valgrind运行时,我得到错误Uninitialised value was created by a heap allocation
和Conditional jump or move depends on uninitialised value(s)
。当我调用像printf
或strlen
这样的函数时,这些错误会随意(有时)出现,如上面的代码所示。
如果我使用calloc
而不是malloc
/ realloc
,则会对此问题进行排序,但随后重新分配过程变得更加混乱。
如果程序正常工作,Valgrind错误是否可以忽略?不将内存初始化为零会有什么影响?如果不能忽视这一点,那么最好的设计是什么呢?
你应该在字符串的末尾放一个字符串终止符。
PS:如果你想清除一些内存使用memset,它比for循环更快
使用calloc,它比malloc和memset好得多。
char *string = calloc( 100 , sizeof(char*));
// Calloc automatically fills the memory blocks
// Its much faster than malloc and memset
// In addition , only in C you don't need typecast for memory allocators