P
Pep
I have recently eradicated a lot of memory leaks in a very old C++
source set. However, whilst they were all fairly easy to resolve, I am
confused by the last one. This seems to be related to throwing a
std::exception with a string object.
This is the test program
=============================================================================
#include <sstream>
#include <iostream>
#include <stdlib.h>
#include <stdexcept>
int main(int argc, char** argv)
{
std:stringstream os;
os << "Test string";
throw std:ut_of_range(os.str());
return(0);
}
=============================================================================
and this is the output from valgrind when I run it
=============================================================================
[[email protected] trunk]$ g++ -o test-ostringstream test-
ostringstream.cc
[[email protected] trunk]$ valgrind --leak-check=yes ./test-
ostringstream
==23358== Memcheck, a memory error detector.
==23358== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et
al.
==23358== Using LibVEX rev 1854, a library for dynamic binary
translation.
==23358== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==23358== Using valgrind-3.3.1, a dynamic binary instrumentation
framework.
==23358== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et
al.
==23358== For more details, rerun with: -v
==23358==
==23358==
==23358== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 19 from
1)
==23358== malloc/free: in use at exit: 2,184 bytes in 3 blocks.
==23358== malloc/free: 3 allocs, 0 frees, 2,184 bytes allocated.
==23358== For counts of detected errors, rerun with: -v
==23358== searching for pointers to 3 not-freed blocks.
==23358== checked 104,152 bytes.
==23358==
==23358== 960 bytes in 1 blocks are possibly lost in loss record 2 of
3
==23358== at 0x401AD81: operator new(unsigned) (vg_replace_malloc.c:
224)
==23358== by 0x409D0F0: std::__default_alloc_template<true,
0>::_S_chunk_alloc(unsigned, int&) (stl_alloc.h:109)
==23358== by 0x409CFFC: std::__default_alloc_template<true,
0>::_S_refill(unsigned) (stl_alloc.h:561)
==23358== by 0x409CB6B: std::__default_alloc_template<true,
0>::allocate(unsigned) (stl_alloc.h:365)
==23358== by 0x40A2B67: std::string::_Rep::_S_create(unsigned,
std::allocator<char> const&) (stl_alloc.h:685)
==23358== by 0x40A38F4: char*
std::string::_S_construct<char*>(char*, char*, std::allocator<char>
const&, std::forward_iterator_t
ag) (basic_string.tcc:154)
==23358== by 0x40A2F84: std::string::string<char*>(char*, char*,
std::allocator<char> const&) (basic_string.h:732)
==23358== by 0x4097959: std::basic_stringbuf<char,
std::char_traits<char>, std::allocator<char> >::str() const
(stl_alloc.h:664)
==23358== by 0x409A57B: std::basic_ostringstream<char,
std::char_traits<char>, std::allocator<char> >::str() const (sstream:
301)
==23358== by 0x8048B84: main (in /mgr/shared/home/pwalker/tweb/
tweb_release/trunk/test-ostringstream)
==23358==
==23358==
==23358== 1,136 bytes in 1 blocks are possibly lost in loss record 3
of 3
==23358== at 0x401AD81: operator new(unsigned) (vg_replace_malloc.c:
224)
==23358== by 0x409CB02: std::__default_alloc_template<true,
0>::allocate(unsigned) (stl_alloc.h:109)
==23358== by 0x40A2B67: std::string::_Rep::_S_create(unsigned,
std::allocator<char> const&) (stl_alloc.h:685)
==23358== by 0x40A2C98:
std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned)
(basic_string.tcc:474)
==23358== by 0x40A0A05: std::string::reserve(unsigned)
(basic_string.h:237)
==23358== by 0x4097C28: std::basic_stringbuf<char,
std::char_traits<char>, std::allocator<char> >:verflow(int)
(sstream.tcc:103
)
==23358== by 0x409DED3: std::basic_streambuf<char,
std::char_traits<char> >::xsputn(char const*, int) (char_traits.h:161)
==23358== by 0x40948D0: std:stream::write(char const*, int)
(streambuf:340)
==23358== by 0x4094FE5: std::basic_ostream<char,
==23358== by 0x8048B6B: main (in /mgr/shared/home/pwalker/tweb/
tweb_release/trunk/test-ostringstream)
==23358==
==23358== LEAK SUMMARY:
==23358== definitely lost: 0 bytes in 0 blocks.
==23358== possibly lost: 2,096 bytes in 2 blocks.
==23358== still reachable: 88 bytes in 1 blocks.
==23358== suppressed: 0 bytes in 0 blocks.
==23358== Reachable blocks (those to which a pointer was found) are
not shown.
==23358== To see them, rerun with: --leak-check=full --show-
reachable=yes
Aborted
=============================================================================
If I remove the throw, then valgrind says everything is fine. So my
question is whether this is expected behavior from the throw and if
not, how do I solve it?
TIA
source set. However, whilst they were all fairly easy to resolve, I am
confused by the last one. This seems to be related to throwing a
std::exception with a string object.
This is the test program
=============================================================================
#include <sstream>
#include <iostream>
#include <stdlib.h>
#include <stdexcept>
int main(int argc, char** argv)
{
std:stringstream os;
os << "Test string";
throw std:ut_of_range(os.str());
return(0);
}
=============================================================================
and this is the output from valgrind when I run it
=============================================================================
[[email protected] trunk]$ g++ -o test-ostringstream test-
ostringstream.cc
[[email protected] trunk]$ valgrind --leak-check=yes ./test-
ostringstream
==23358== Memcheck, a memory error detector.
==23358== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et
al.
==23358== Using LibVEX rev 1854, a library for dynamic binary
translation.
==23358== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==23358== Using valgrind-3.3.1, a dynamic binary instrumentation
framework.
==23358== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et
al.
==23358== For more details, rerun with: -v
==23358==
==23358==
==23358== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 19 from
1)
==23358== malloc/free: in use at exit: 2,184 bytes in 3 blocks.
==23358== malloc/free: 3 allocs, 0 frees, 2,184 bytes allocated.
==23358== For counts of detected errors, rerun with: -v
==23358== searching for pointers to 3 not-freed blocks.
==23358== checked 104,152 bytes.
==23358==
==23358== 960 bytes in 1 blocks are possibly lost in loss record 2 of
3
==23358== at 0x401AD81: operator new(unsigned) (vg_replace_malloc.c:
224)
==23358== by 0x409D0F0: std::__default_alloc_template<true,
0>::_S_chunk_alloc(unsigned, int&) (stl_alloc.h:109)
==23358== by 0x409CFFC: std::__default_alloc_template<true,
0>::_S_refill(unsigned) (stl_alloc.h:561)
==23358== by 0x409CB6B: std::__default_alloc_template<true,
0>::allocate(unsigned) (stl_alloc.h:365)
==23358== by 0x40A2B67: std::string::_Rep::_S_create(unsigned,
std::allocator<char> const&) (stl_alloc.h:685)
==23358== by 0x40A38F4: char*
std::string::_S_construct<char*>(char*, char*, std::allocator<char>
const&, std::forward_iterator_t
ag) (basic_string.tcc:154)
==23358== by 0x40A2F84: std::string::string<char*>(char*, char*,
std::allocator<char> const&) (basic_string.h:732)
==23358== by 0x4097959: std::basic_stringbuf<char,
std::char_traits<char>, std::allocator<char> >::str() const
(stl_alloc.h:664)
==23358== by 0x409A57B: std::basic_ostringstream<char,
std::char_traits<char>, std::allocator<char> >::str() const (sstream:
301)
==23358== by 0x8048B84: main (in /mgr/shared/home/pwalker/tweb/
tweb_release/trunk/test-ostringstream)
==23358==
==23358==
==23358== 1,136 bytes in 1 blocks are possibly lost in loss record 3
of 3
==23358== at 0x401AD81: operator new(unsigned) (vg_replace_malloc.c:
224)
==23358== by 0x409CB02: std::__default_alloc_template<true,
0>::allocate(unsigned) (stl_alloc.h:109)
==23358== by 0x40A2B67: std::string::_Rep::_S_create(unsigned,
std::allocator<char> const&) (stl_alloc.h:685)
==23358== by 0x40A2C98:
std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned)
(basic_string.tcc:474)
==23358== by 0x40A0A05: std::string::reserve(unsigned)
(basic_string.h:237)
==23358== by 0x4097C28: std::basic_stringbuf<char,
std::char_traits<char>, std::allocator<char> >:verflow(int)
(sstream.tcc:103
)
==23358== by 0x409DED3: std::basic_streambuf<char,
std::char_traits<char> >::xsputn(char const*, int) (char_traits.h:161)
==23358== by 0x40948D0: std:stream::write(char const*, int)
(streambuf:340)
==23358== by 0x4094FE5: std::basic_ostream<char,
stream<char, std::char_traits<char> >&, char const*) (ostream.tcc:640)std::char_traits said:(std::basic_o
==23358== by 0x8048B6B: main (in /mgr/shared/home/pwalker/tweb/
tweb_release/trunk/test-ostringstream)
==23358==
==23358== LEAK SUMMARY:
==23358== definitely lost: 0 bytes in 0 blocks.
==23358== possibly lost: 2,096 bytes in 2 blocks.
==23358== still reachable: 88 bytes in 1 blocks.
==23358== suppressed: 0 bytes in 0 blocks.
==23358== Reachable blocks (those to which a pointer was found) are
not shown.
==23358== To see them, rerun with: --leak-check=full --show-
reachable=yes
Aborted
=============================================================================
If I remove the throw, then valgrind says everything is fine. So my
question is whether this is expected behavior from the throw and if
not, how do I solve it?
TIA