I'm trying to understand why Valgrind is spitting out :
==3409== Invalid read of size 8
==3409== at 0x4EA3B92: __GI_strlen (strlen.S:31)
whenever I'm applying strlen on a dynamically allocated string?
Here is a short testcase :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *hello = "Hello World";
char *hello2;
/* Step 1 */
printf("Step 1\n");
printf("strlen : %lu\n",(unsigned long)strlen(hello));
/* Step 2 */
hello2 = calloc(12,sizeof(char));
hello2[0] = 'H';
hello2[1] = 'e';
hello2[2] = 'l';
hello2[3] = 'l';
hello2[4] = 'o';
hello2[5] = ' ';
hello2[6] = 'W';
hello2[7] = 'o';
hello2[8] = 'r';
hello2[9] = 'l';
hello2[10] = 'd';
hello2[11] = 0;
printf("Step 2\n");
printf("strlen : %lu\n",(unsigned long)strlen(hello2));
free(hello2);
return 0;
}
And here is the result output from Valgrind :
lenain@perseus:~/work/leaf$ valgrind ./leaf
==3409== Memcheck, a memory error detector
==3409== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==3409== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for copyright info
==3409== Command: ./leaf
==3409==
Step 1
strlen : 11
Step 2
==3409== Invalid read of size 8
==3409== at 0x4EA3B92: __GI_strlen (strlen.S:31)
==3409== by 0x40098A: main (in /home/lenain/work/leaf/leaf)
==3409== Address 0x5189048 is 8 bytes inside a block of size 12 alloc'd
==3409== at 0x4C234CB: calloc (vg_replace_malloc.c:418)
==3409== by 0x4008F0: main (in /home/lenain/work/leaf/leaf)
==3409==
strlen : 11
==3409==
==3409== HEAP SUMMARY:
==3409== in use at exit: 0 bytes in 0 blocks
==3409== total heap usage: 1 allocs, 1 frees, 12 bytes allocated
==3409==
==3409== All heap blocks were freed -- no leaks are possible
==3409==
==3409== For counts of detected and suppressed errors, rerun with: -v
==3409== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
What is the correct way to avoid these warnings? Are they real warnings?
This is most likely related to this bugreport:
https://bugzilla.redhat.com/show_bug.cgi?id=518247
As Paul already suggested, strlen() on intel platforms optionally uses SSE optimization to speed up strlen and friends. This speed up involve safe reads behind the allocated blocks, something older versions of valgrind did not understand yet. So upgrade your valgrind and you will be OK.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With