On 22-Apr-2014 21:12, liamw wrote:
Imagine a program like this:
int main() { int *p; { int x = 0; p = &x; } return *p; }
Not to bad mouth the clang output too much, but it is a long, long way from what it should be, something along the lines of:
"pointer to out of scope variable at line 321 of test.c"
Unfortunately this is one of the situations where valgrind is not very helpful. Here is a slightly more complicated example:
cat >test.cpp <<EOD #include <iostream> int sub(void) { int *p; { int x = 123; p = &x; } std::cout << "value of p " << *p << std::endl; return *p; } int main() { int ret = sub(); std::cout << "value of ret " << ret << std::endl; return ret; } EOD g++ -Wall -g -O0 -o test test.cpp ./test value of p 123 value of ret 123 valgrind ./test #no problems reported
The reason the program reports these values, even though the memory is out of scope when the values are reported, is that the value stored there has not (yet) changed and the memory location has not been explicitly released. The reason valgrind doesn't complain is because it only keeps track of memory locations, not scope, and it saw that x was set, so it doesn't trigger the warning about a read from uninitialized memory. The value was probably stored on a stack because there was no explicit free() or delete() for valgrind to catch. If it were possible to make the compiler not store method/function variables on the stack then valgrind could catch these - but I don't know how to do that with the gnu compilers.
Note that if an explicit malloc/free pair was employed to emulate scope (sort of), then valgrind would have no problems detecting this issue:
cat >test.cpp <<EOD #include <iostream> #include <stdlib.h> int sub(void) { int *p; { p = (int *) malloc(sizeof(int)); *p=123; free(p); } std::cout << "value of p " << *p << std::endl; return *p; } int main() { int ret = sub(); std::cout << "value of ret " << ret << std::endl; return ret; } EOD g++ -Wall -g -O0 -o test test.cpp ./test value of p 0 value of ret 0 valgrind ./test #part of output ==2769== Invalid read of size 4 ==2769== at 0x80486E1: sub() (test.cpp:12) ==2769== by 0x804872B: main (test.cpp:16) ==2769== Address 0x432b028 is 0 bytes inside a block of size 4 free'd ==2769== at 0x402B06C: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==2769== by 0x80486DD: sub() (test.cpp:10) ==2769== by 0x804872B: main (test.cpp:16) ==2769== value of p 123 ==2769== Invalid read of size 4 ==2769== at 0x8048716: sub() (test.cpp:13) ==2769== by 0x804872B: main (test.cpp:16) ==2769== Address 0x432b028 is 0 bytes inside a block of size 4 free'd ==2769== at 0x402B06C: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==2769== by 0x80486DD: sub() (test.cpp:10) ==2769== by 0x804872B: main (test.cpp:16) ==2769== value of ret 123
This type of memory issue is discussed in some depth here:
http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-a...
Regards,
David Mathog mathog@...1176... Manager, Sequence Analysis Facility, Biology Division, Caltech