I havent used valgrind before but I think it should detect some memory errors.
My code:
#include <stdio.h>
unsigned int a[2];
int main()
{
a[-1] = 21;
printf("%d,", a[-1]);
return 1;
}
As you can see, I am accessing a[-1] which I should not.
How am I using valgrind?
I am compiling with gcc -g -O0 codeFile.c
And executing: valgrind -s ./a.out
Result is:
==239== Memcheck, a memory error detector
==239== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==239== Using Valgrind-3.16.0.GIT and LibVEX; rerun with -h for copyright info
==239== Command: ./a.out
==239== 21,==239==
==239== HEAP SUMMARY:
==239== in use at exit: 0 bytes in 0 blocks
==239== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==239==
==239== All heap blocks were freed -- no leaks are possible
==239==
==239== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Shouldnt valgrind find these error, or am I using it wrong?
EDIT: It seems that valgrind memcheck does not do anything for global variables and as suggested in the answers/comments that it should work with indexes further from the pointer, therefore: I removed the global declaration and added it insude main, and accessed a[-10] instead of a[1]. Same behaviour.
int main()
{
unsigned int a[2];
a[-10] = 21;
printf("%d,", a[-10]);
return 1;
}
It actually throws error if I use a[-100] though. Whats the deal?
EDIT 2
Furthermore, why this has no errors
while (i <= 2)
{
j = a[i];
i++;
}
But this does
while (i <= 2)
{
printf("%d,", a[i]);
i++;
}
Valgrind usually can't find memory errors where the memory being modified is at a negative offset from the current stack pointer or memory that coincides with another variable in memory.
For example, if
awas on the stack,a[3]would triggermemcheck.a[-1]would not, because that, for all Valgrind knows, could easily be valid memory.To expand on that, here's a quote from the documentation with my emphasis added:
This quote is actually partially incorrect; when it says "below the stack pointer" it really means at a positive offset from the stack pointer, or interfering with another function's stack memory.
I should also note that (from your second edit) Valgrind doesn't actually complain until the value is used in some meaningful way. Assignment is, in Valgrind's eyes, not using the value in a meaningful way. Here's another quote to back that up with my emphasis added:
Because
ais a global variable, you'll have a hard time trying to check the memory of it. One Valgrind tool I've used before that deals with this isexp-sgcheck(experimental static and global variable check), although I've found it to be unreliable (most likely due to it being experimental).An easier and better way to detect these would be to enable compiler warnings or use a static analyzer (my favorite is LLVM's
scan-build).