Valgrind found both the uninitialized read and write, but it seems that it only flags the read from uninitialized memory once we print it; it's not clear whether that bug would still be caught if we were to use the value differently ==16114== Memcheck, a memory error detector. ==16114== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al. ==16114== Using LibVEX rev 1471, a library for dynamic binary translation. ==16114== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP. ==16114== Using valgrind-3.1.0, a dynamic binary instrumentation framework. ==16114== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al. ==16114== For more details, rerun with: -v ==16114== Hello world! Now reading uninitialized memory Did you notice? (value was ==16114== Conditional jump or move depends on uninitialised value(s) ==16114== at 0x40A2F8F: std::ostreambuf_iterator > std::num_put > >::_M_convert_int(std::ostreambuf_iterator >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.5.0.7) ==16114== by 0x40A2BDF: std::num_put > >::do_put(std::ostreambuf_iterator >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.5.0.7) ==16114== by 0x40B86FB: std::ostream::operator<<(long) (in /usr/lib/libstdc++.so.5.0.7) ==16114== by 0x40B8BEC: std::ostream::operator<<(int) (in /usr/lib/libstdc++.so.5.0.7) ==16114== by 0x804882A: main (wrong3.cc:12) ==16114== ==16114== Use of uninitialised value of size 4 ==16114== at 0x40B36D4: (within /usr/lib/libstdc++.so.5.0.7) ==16114== by 0x40A2FBC: std::ostreambuf_iterator > std::num_put > >::_M_convert_int(std::ostreambuf_iterator >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.5.0.7) ==16114== by 0x40A2BDF: std::num_put > >::do_put(std::ostreambuf_iterator >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.5.0.7) ==16114== by 0x40B86FB: std::ostream::operator<<(long) (in /usr/lib/libstdc++.so.5.0.7) ==16114== by 0x40B8BEC: std::ostream::operator<<(int) (in /usr/lib/libstdc++.so.5.0.7) ==16114== by 0x804882A: main (wrong3.cc:12) ==16114== ==16114== Conditional jump or move depends on uninitialised value(s) ==16114== at 0x40B36E0: (within /usr/lib/libstdc++.so.5.0.7) ==16114== by 0x40A2FBC: std::ostreambuf_iterator > std::num_put > >::_M_convert_int(std::ostreambuf_iterator >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.5.0.7) ==16114== by 0x40A2BDF: std::num_put > >::do_put(std::ostreambuf_iterator >, std::ios_base&, char, long) const (in /usr/lib/libstdc++.so.5.0.7) ==16114== by 0x40B86FB: std::ostream::operator<<(long) (in /usr/lib/libstdc++.so.5.0.7) ==16114== by 0x40B8BEC: std::ostream::operator<<(int) (in /usr/lib/libstdc++.so.5.0.7) ==16114== by 0x804882A: main (wrong3.cc:12) 2) (No memory leak here) Now writing to uninitialized pointer ==16114== ==16114== Use of uninitialised value of size 4 ==16114== at 0x80488A4: main (wrong3.cc:18) Did you notice? There should be 2 errors in this run ==16114== ==16114== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 20 from 1) ==16114== malloc/free: in use at exit: 0 bytes in 0 blocks. ==16114== malloc/free: 1 allocs, 1 frees, 4 bytes allocated. ==16114== For counts of detected errors, rerun with: -v ==16114== No malloc'd blocks -- no leaks are possible.