|
From: Bastien C. <ba...@ch...> - 2003-04-09 13:45:07
|
Hello there,
I have serious troubles with possible memory leaks in programs heavily
using the STL. I am not able to tell whether it is a problem with the
compiler, the STL or wrong valgrind output, so I'll start here before
filing in a gcc bug report.
One of my programs grew larger and larger without I knew why, so took
valgrind to look and started building testcases to find out what was
happening. I have a SuSE 8.1 distribution, that's kernel 2.4.x,
glibc2.2 and gcc version 3.2
Consider this test case example:
-------------------------------------------------------
#include <vector>
#include <ext/hash_map>
using namespace __gnu_cxx;
void f1()
{
int n=3D42;
vector<int> v;
for(int i=3D0; i<1000000; i++) v.push_back(n);
}
int main(){
f1();
return 0;
}
----------------------------------------------------------
g++ -g -o test test.C=20
and then=20
valgrind --leak-resolution=3Dhigh --num-callers=3D20 --show-reachable=3Dy=
es --leak-check=3Dyes ./test
I will get the following summary:
----------------------------------------------------------
=3D=3D16880=3D=3D LEAK SUMMARY:
=3D=3D16880=3D=3D definitely lost: 16 bytes in 1 blocks.
=3D=3D16880=3D=3D possibly lost: 0 bytes in 0 blocks.
=3D=3D16880=3D=3D still reachable: 6912 bytes in 4 blocks.
----------------------------------------------------------
The number which troubles me ist the bytes that are still
reachable. Here's, the detail:
----------------------------------------------------------
=3D=3D19169=3D=3D 6848 bytes in 3 blocks are still reachable in loss reco=
rd 3 of 3
=3D=3D19169=3D=3D at 0x4015DE3B: __builtin_new (vg_clientfuncs.c:129)
=3D=3D19169=3D=3D by 0x4015DE76: operator new(unsigned) (vg_clientfunc=
s.c:142)
=3D=3D19169=3D=3D by 0x40278E00: std::__default_alloc_template<true, 0=
>::_S_chunk_alloc(unsigned, int&) (in /usr/lib/libstdc++.so.5.0.0)
=3D=3D19169=3D=3D by 0x40278D1C: std::__default_alloc_template<true, 0=
>::_S_refill(unsigned) (in /usr/lib/libstdc++.so.5.0.0)
=3D=3D19169=3D=3D by 0x402788EF: std::__default_alloc_template<true, 0=
>::allocate(unsigned) (in /usr/lib/libstdc++.so.5.0.0)
=3D=3D19169=3D=3D by 0x8049008: std::__simple_alloc<int, std::__defaul=
t_alloc_template<true, 0> >::allocate(unsigned) (/usr/include/g++/bits/st=
l_alloc.h:224)
=3D=3D19169=3D=3D by 0x8048D7E: std::_Vector_alloc_base<int, std::allo=
cator<int>, true>::_M_allocate(unsigned) (/usr/include/g++/bits/stl_vecto=
r.h:121)
=3D=3D19169=3D=3D by 0x8048A45: std::vector<int, std::allocator<int> >=
::_M_insert_aux(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::=
allocator<int> > >, int const&) (/usr/include/g++/bits/stl_vector.h:898)
=3D=3D19169=3D=3D by 0x804884C: std::vector<int, std::allocator<int> >=
::push_back(int const&) (/usr/include/g++/bits/stl_vector.h:496)
=3D=3D19169=3D=3D by 0x80486A1: f1() (test2.C:10)
=3D=3D19169=3D=3D by 0x80487A2: main (test2.C:21)
=3D=3D19169=3D=3D by 0x403094A1: __libc_start_main (in /lib/libc.so.6)
=3D=3D19169=3D=3D by 0x8048580: (within /home/bach/work/assembly/htga/=
src/progs/test)
----------------------------------------------------------
Regarding the program above, I sincerely do think that there should be
no leak at all, even not in "reachable" parts.
Now, a few bytes don't hurt. Unfortunately, when I let run my real
program, here's what I get (for really small data sets):
----------------------------------------------------------
=3D=3D698=3D=3D LEAK SUMMARY:
=3D=3D698=3D=3D definitely lost: 24825 bytes in 3492 blocks.
=3D=3D698=3D=3D possibly lost: 1398 bytes in 3 blocks.
=3D=3D698=3D=3D still reachable: 1125492 bytes in 65 blocks.
----------------------------------------------------------
(please note that I don't care about the that the definitely and
possibly lost numbers, these I can trace back to real oversights in my
code.)
The "still reachable" 1M number is about 40 times greater than the
other two numbers added together and I have the distinct impression
that the memory is really eaten away somewhere:=20
1) all valgrind detail messages are more or less similar to the one of
the test case above, all have something to do with containers
2) putting a "while(1)" loop at a distinctive point in my program
where everything should have been more or less freed after some
heavy computation (using about any existing STL container type
that exists with dozens of different classes) gives me remaining
memory footprints of >1G (yes, that's gigabyte).
Now my question: any idea where to start searching? is valgrind at
fault (which I don't think, but one never knows)? the gnu STL? the gnu
g++ compiler?
Any suggestion welcome.=20
Regards,
Bastien
--=20
-- The universe has its own cure for stupidity. --
-- Unfortunately, it doesn't always apply it. --
|