我想了解valgrind日志消息并使用以下代码
#include <iostream>
int main()
{
int numbers[] = {1,2,3,4,5,6,7,8,9,10};
int length = sizeof(numbers) / sizeof(numbers[0]);
std::cout << "length: " << length << std::endl;
for (int i = 0; i < length + 10; ++i)
{
int number = numbers[i];
if (number > 5)
{
std::cout << number << " is greater than 5" << std::endl;
} else {
std::cout << number << " is less or equal 5" << std::endl;
}
}
}
产生未初始化的值。如果我在valgrind中运行该程序,则不会收到相应的消息。如果我运行for循环的长度为+ 10,则valgrind会检测到未初始化的值。
为什么valgrind这么晚才检测到单位值?
==2484== Conditional jump or move depends on uninitialised value(s)
==2484== at 0x108A3C: main (arrays.cpp:11)
==2484== Uninitialised value was created by a stack allocation
==2484== at 0x51E6ABB: (below main) (libc-start.c:137)
==2484==
==2484== Conditional jump or move depends on uninitialised value(s)
==2484== at 0x4F43C0A: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x108A85: main (arrays.cpp:15)
==2484== Uninitialised value was created by a stack allocation
==2484== at 0x51E6ABB: (below main) (libc-start.c:137)
==2484==
==2484== Use of uninitialised value of size 8
==2484== at 0x4F4370E: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x4F43C33: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x108A85: main (arrays.cpp:15)
==2484== Uninitialised value was created by a stack allocation
==2484== at 0x51E6ABB: (below main) (libc-start.c:137)
==2484==
==2484== Conditional jump or move depends on uninitialised value(s)
==2484== at 0x4F4371B: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x4F43C33: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x108A85: main (arrays.cpp:15)
==2484== Uninitialised value was created by a stack allocation
==2484== at 0x51E6ABB: (below main) (libc-start.c:137)
==2484==
==2484== Conditional jump or move depends on uninitialised value(s)
==2484== at 0x4F43C66: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484== by 0x108A85: main (arrays.cpp:15)
==2484== Uninitialised value was created by a stack allocation
==2484== at 0x51E6ABB: (below main) (libc-start.c:137)
编辑:我更改了代码。这是我使用的整个代码。编译:g ++ -c -g3 arrays.cpp arrays.cppvalgrind:valgrind --tool = memcheck --track-origins = yes --num-callers = 100 --log-file = uv_log.txt ./arrays
编辑2:
length: 10
1 is less or equal 5
2 is less or equal 5
3 is less or equal 5
4 is less or equal 5
5 is less or equal 5
6 is greater than 5
7 is greater than 5
8 is greater than 5
9 is greater than 5
10 is greater than 5
-882498304 is less or equal 5
-188984184 is less or equal 5
1084208 is greater than 5
0 is less or equal 5
85879703 is greater than 5
0 is less or equal 5
0 is less or equal 5
您实际上没有检查未初始化的访问。您检查索引是否超出范围。在您的情况下,越界访问位于堆栈上,因此您可以访问堆栈上的某些内存。而且您很幸运,因为整个访问区域都在堆栈中,所以您不会收到无效的读取。您的程序读取堆栈的某些数据,该数据恰好在length+1
情况下被初始化(因为其中写入了其他内容,例如,它可以是函数参数,其他局部变量或函数的返回地址),因此valgrind无法报告任何错误。
但是对于length+10
,它足够大,可以实际从一些未初始化的存储器中读取。而且我敢打赌,如果将10
增大到更大的数字,则会得到无效的读取(这会导致分段错误)。