I am trying to implement a function that uses malloc in it. When I run it using valgrind, it reports the following errors like this:
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)
And there are a lot of invalid writes due to malloc. I really don't understand this, what is the reason of malloc creating invalid writes? I didn't allocate temp_rep anywhere other than in this function, and I made sure to free each temp_rep after testing.
//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;
}
}
The invalid write isn't due to malloc
. The message says it's due to a strcmp
call that's working with a buffer returned from malloc
.
It says it reads past the end of a malloc'ed buffer whose size is 1. That looks suspicious for a string. If you look at where you allocated the memory:
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;
}
You allocate 1 byte and store the character '0'
there. But apparently temp_rep
is supposed to be string, which means you didn't null terminate it. You need to allocate one additional byte for the null terminator and set is:
char* temp_rep=malloc(2);
temp_rep[0]='0';
temp_rep[1]=0;
return temp_rep;
You have similar issues in the else
block where you don't leave space for the null terminator, and you're using sizeof
on temp_rep
and hex_rep
(which gets you the size of the pointers, not the string they contain) instead of strlen
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.