valgrind在mallocing时报告无效读取
我正在尝试实现一个在其中使用malloc的函数。当我使用valgrind运行它时,它会报告如下错误:valgrind在mallocing时报告无效读取,c,valgrind,C,Valgrind,我正在尝试实现一个在其中使用malloc的函数。当我使用valgrind运行它时,它会报告如下错误: Invalid read of size 1 ==11870== at 0x4C33DC7: strcmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==11870== by 0x10A864: testFormatAsHex (apintTests.c:212) ==11870== by 0x109351
Invalid read of size 1
==11870== at 0x4C33DC7: strcmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11870== by 0x10A864: testFormatAsHex (apintTests.c:212)
==11870== by 0x109351: main (apintTests.c:72)
==11870== Address 0x55cd4e1 is 0 bytes after a block of size 1 alloc'd
==11870== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11870== by 0x10B989: apint_format_as_hex (apint.c:225)
==11870== by 0x10A84D: testFormatAsHex (apintTests.c:212)
==11870== by 0x109351: main (apintTests.c:72)
由于malloc,存在大量无效写入。我真的不明白,malloc创建无效写入的原因是什么?除了在这个函数中,我没有在任何地方分配temp_rep,我确保在测试后释放每个temp_rep
//loop over the array, transforming each u64 number to hex;placing it in array
//and realloc returning array when placing a char in it
long length=ap->length;
int i;
int hex_pos=0;
//store the largest without appending zeroes
if (ap->bin_string[length-1]==0UL){
char* temp_rep=malloc(sizeof(char));
temp_rep[hex_pos]='0';
return temp_rep;
}
else{
int most_sig_bits=ceil(log2(apint_get_bits(ap,length-1)));
int temp_length=ceil((float)most_sig_bits/4);
char* temp_rep=malloc(temp_length*sizeof(char));
uint64_t lar_val=ap->bin_string[length-1];
sprintf(temp_rep,"%lx",lar_val);
//for rest of the terms in array, store them padded
for(i=length-2;i>=0;i--){
char *hex_rep=malloc(16*sizeof(char));
uint64_t val=ap->bin_string[i];
sprintf(hex_rep,"%016lx",val);
temp_rep=realloc(temp_rep,sizeof(temp_rep)+sizeof(hex_rep));
temp_rep=strcat(temp_rep,hex_rep);
free(hex_rep);
}
return temp_rep;
}
}
无效写入不是由于
malloc
造成的。消息说这是由于使用从malloc
返回的缓冲区的strcmp
调用造成的
它说它读取的数据超过了一个大小为1的malloc'ed缓冲区的末尾。这看起来很可疑。如果查看分配内存的位置:
int hex_pos=0;
//store the largest without appending zeroes
if (ap->bin_string[length-1]==0UL){
char* temp_rep=malloc(sizeof(char));
temp_rep[hex_pos]='0';
return temp_rep;
}
分配1个字节并将字符'0'
存储在那里。但显然,temp_rep
应该是字符串,这意味着您没有使用null终止它。您需要为空终止符分配一个额外字节,设置为:
char* temp_rep=malloc(2);
temp_rep[0]='0';
temp_rep[1]=0;
return temp_rep;
在
else
块中也存在类似的问题,在该块中没有为空终止符留出空间,并且在temp_rep
和hex_rep
上使用sizeof
(这会获取指针的大小,而不是指针包含的字符串)读取问题不是因为strlen,而是因为没有正确终止字符串而导致的。写入问题可能是因为您没有记住为字符串末尾的空字节分配足够的空间。如果您正确使用Valgrind,它将报告行号,这使得解决问题变得容易。故障不在malloc()
;这是您使用malloc()
的方式。您还需要阅读有关创建MCVE(-或MRE或现在使用的任何名称)的内容。我们需要完整的函数来帮助您。Valgrind报告无效的读入strcmp
,而不是malloc
。问题应该出现在apintTests.c:212
代码行。