Valgrind提出这些投诉
Conditional jump or move depends on uninitialised value(s)
==8443== at 0x40070F: main (test.c:31)
==8443== Uninitialised value was created by a heap allocation
==8443== at 0x4C29BCF: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==8443== by 0x4EA4847: getdelim (in /usr/lib64/libc-2.20.so)
==8443== by 0x40079E: main (test.c:24)
第31行是指if(line[i] == '(' || line[i] == '{' || line[i] == '[')
下方的行,第24行是指while (getline(&line, &len, fp) != -1) {
下面的行。
int main(){
FILE * fp;
char * line = NULL;
size_t len = 0;
fp = fopen("test.json", "r");
if (fp == NULL)
return 0;
while (getline(&line, &len, fp) != -1) {
if(!line)
break;
int i;
// Go through each letter
for(i = 0; i<len; i++){
if(line[i] == '(' || line[i] == '{' || line[i] == '[')
printf("%c",line[i]);
}
if(line)
free(line);
line = NULL;
len = 0;
}
fclose(fp);
if (line)
free(line);
return 1;
}
我已经对其他类似问题的问题进行了一些搜索,这让我尝试在while循环结束时释放行并重新初始化这两个变量,但我不断得到这个抱怨并且无法弄清楚这是为什么。
我做错了什么?
答案 0 :(得分:0)
问题在于您使用getline()
的方式。
从联系手册:
“...成功通话时,* lineptr和* n将分别更新以反映缓冲区地址和分配的大小。”
“成功时,getline()
和getdelim()
返回读取的字符数,包括分隔符,但不包括终止空字节('\ 0')。”
它并没有说分配的数量与读取的字节数完全匹配...实际上,在我的系统上,分配的缓冲区似乎总是至少120个字节,无论读入多少个字符。我认为这是出于性能原因 - getline()
只要在realloc()
之前足够大,line
就会回收缓冲区。此外,因为getline()可以在重复调用时重用相同的缓冲区(并且如果缓冲区太小,将重新分配缓冲区),如果在最后一个{之前没有释放getline()
,则代码将表现更好。 {1}}。
要修复代码,您将执行以下操作:
int main( void )
{
FILE *fp;
char *line = NULL;
size_t len=0;
ssize_t bytesread;
int i,j=1;
fp = fopen( "test.json", "r" );
if ( fp == NULL )
return 0;
while ( (bytesread=getline( &line, &len, fp )) != -1 )
{
// This demonstrates the point:
printf("line %3d len: %d bytesread: %d\n", j++, len, bytesread);
if ( !line )
break;
// Go through each letter
for ( i = 0; i < bytesread; i++ ) {
if(line[i] == '(' || line[i] == '{' || line[i] == '[')
printf( "%c", line[i] );
}
}
fclose( fp );
free( line );
return 0; // traditionally in C, 0 means success.
// if you include stdlib.h, you could use the EXIT_SUCCESS macro.
}