473,378 Members | 1,380 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

Possible memory leak?

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::ostringstream os;
os << "Test string";
throw std::out_of_range(os.str());

return(0);
}
================================================== ===========================

and this is the output from valgrind when I run it

================================================== ===========================
[pw*****@mgr1.tweb.eudev1 trunk]$ g++ -o test-ostringstream test-
ostringstream.cc
[pw*****@mgr1.tweb.eudev1 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<charconst&) (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<charconst&) (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<charconst&) (stl_alloc.h:685)
==23358== by 0x40A2C98:
std::string::_Rep::_M_clone(std::allocator<charcon st&, 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::overflow(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::ostream::write(char const*, int)
(streambuf:340)
==23358== by 0x4094FE5: std::basic_ostream<char,
std::char_traits<char& std::operator<< <std::char_traits<char>
>(std::basic_o
stream<char, std::char_traits<char&, char const*) (ostream.tcc:640)
==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
Jul 21 '08 #1
13 4305
Pep wrote:
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::ostringstream os;
os << "Test string";
throw std::out_of_range(os.str());

return(0);
}
================================================== ===========================
>
and this is the output from valgrind when I run it
[snip]
>
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?
The following is valgrind-clean on my platform:

#include <sstream>
#include <iostream>
#include <stdlib.h>
#include <stdexcept>

int main(int argc, char** argv)
{
try {
std::ostringstream os;
os << "Test string";
throw std::out_of_range(os.str());
}
catch ( std::exception const & e ) {
std::cerr << "exception propagated into main: "
<< e.what() << "\n";
}
catch ( ... ) {
std::cerr << "unidentified thing caught in main.\n";
}
return(0);
}
Best

Kai-Uwe Bux
Jul 21 '08 #2
The following is valgrind-clean on my platform:
>
#include <sstream>
#include <iostream>
#include <stdlib.h>
#include <stdexcept>

int main(int argc, char** argv)
{
* try {
* * * * std::ostringstream os;
* * * * os << "Test string";
* * * * throw std::out_of_range(os.str());
* }
* catch ( std::exception const & e ) {
* * std::cerr << "exception propagated into main: "
* * * * * * * << e.what() << "\n";
* }
* catch ( ... ) {
* * std::cerr << "unidentified thing caught in main.\n";
* }
* return(0);

}
Does this mean that having an exception thrown without being caught
causes a memory leak ?
Jul 21 '08 #3
kh*******@gmail.com wrote:
Does this mean that having an exception thrown without being caught
causes a memory leak ?
Exceptions should always be caught. If an exception is thrown out of
main(), bad things can happen (at least with some compilers and systems).

(OTOH I find it strange that it would leak anything. The stack should
be unwound normally even if it's the main() function.)
Jul 21 '08 #4
On Jul 21, 7:07 pm, Juha Nieminen <nos...@thanks.invalidwrote:
khalid...@gmail.com wrote:
Does this mean that having an exception thrown without being
caught causes a memory leak ?
Exceptions should always be caught. If an exception is thrown
out of main(), bad things can happen (at least with some
compilers and systems).
Such as? The behavior of an uncaught exception is defined by
the standard, and I'm not aware of any compilers which have
problems in this regard.
(OTOH I find it strange that it would leak anything. The stack
should be unwound normally even if it's the main() function.)
If the exception is not caught, it is unspecified whether the
stack is unwound or not---I think that typically, it isn't, so
you still have the information as to where the exception was
thrown in your core dump.

Of course, under a well behaved operating system, nothing leaks,
even if a process terminates abnormally.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jul 21 '08 #5
On Jul 21, 10:07*am, Juha Nieminen <nos...@thanks.invalidwrote:
khalid...@gmail.com wrote:
Does this mean that having an exception thrown without being caught
causes a memory leak ?
* (OTOH I find it strange that it would leak anything. The stack should
be unwound normally even if it's the main() function.)
The thrown object lives somewhere else outside of any stack frame. (I
am not sure whether this is by the standard, or just an implementation
necessity.) So apparently the OP's platform does not destroy that
object if not caught.

Ali
Jul 21 '08 #6
On 2008-07-21 14:57:50 -0400, ac******@gmail.com said:
On Jul 21, 10:07Â*am, Juha Nieminen <nos...@thanks.invalidwrote:
>khalid...@gmail.com wrote:
>>Does this mean that having an exception thrown without being caught
causes a memory leak ?
>Â* (OTOH I find it strange that it would leak anything. The stack should
be unwound normally even if it's the main() function.)

The thrown object lives somewhere else outside of any stack frame. (I
am not sure whether this is by the standard, or just an implementation
necessity.) So apparently the OP's platform does not destroy that
object if not caught.

Ali
Or valgrind is wrong.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jul 21 '08 #7
Pep
On Jul 21, 6:07 pm, Juha Nieminen <nos...@thanks.invalidwrote:
khalid...@gmail.com wrote:
Does this mean that having an exception thrown without being caught
causes a memory leak ?

Exceptions should always be caught. If an exception is thrown out of
main(), bad things can happen (at least with some compilers and systems).

(OTOH I find it strange that it would leak anything. The stack should
be unwound normally even if it's the main() function.)
Hey everyone, thanks for the replies.

Firstly, I did not even think about the fact that the test program and
therefore the live one that it is based on, is not catching the thrown
exception. Seems silly now you pointed it out, as the main program
itself should really handle the exception and then send the error
status back to the cli via a return statement.

As to whether valgrind is simply wrong, that is another good question
that I had been toying with myself, yet loathe to mention. It always
seems easier to blame the tools ;) However, I am loading up some more
memory testers on this dev server, so that I should be able to answer
that question soon enough.

Apologies for not mentioning that the dev server in question is RHEL
3.0

Thanks again for the replies, I'll catch the exception and handle it
correctly now.
Jul 22 '08 #8
On 2008-07-22 06:29:01 -0400, Pep <pe**********@yahoo.co.uksaid:
>
As to whether valgrind is simply wrong, that is another good question
that I had been toying with myself, yet loathe to mention. It always
seems easier to blame the tools ;)
Indeed. But in the case of memory testers, it's not uncommon to get
false positives for resources that are managed in peculiar ways by the
runtime library. Exception objects are not like normal objects, and I
wouldn't be surprised if memory testers sometimes get them wrong.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jul 22 '08 #9
James Kanze wrote:
Of course, under a well behaved operating system, nothing leaks,
even if a process terminates abnormally.
No OS can know if the program created some temporary files which it
intends to delete when it terminates.
Jul 22 '08 #10
On Jul 22, 11:40 pm, Juha Nieminen <nos...@thanks.invalidwrote:
James Kanze wrote:
Of course, under a well behaved operating system, nothing
leaks, even if a process terminates abnormally.
No OS can know if the program created some temporary files
which it intends to delete when it terminates.
Sure it can. Perhaps the most common OS's don't do this, but
they certainly could (and I've used at least one OS which did).
For that matter, it's possible to do so under Unix (but only to
a limited extent).

More generally, of course, you're right in that there will
always be some resources for which it isn't clear whether they
should remain or not. g++ (and probably many other compilers)
has an option to explicitly not delete intermediate files; if
something crashes, they can be very useful for debugging. Is
this a resource leak? I'd say yes, but an intentional one.
For that matter, if I don't catch an exception under Unix, I get
a core dump, which can eat up considerable resources.

Within the context of the original posting, however: if a
program terminates because of an uncaught exception, the system
should recover all of the critical resources, without a stack
walkback, and a stack walkback is likely to destroy resoures,
and above all context, that you want to keep, for debugging
purposes. The standard makes it implementation defined (or
unspecified, I'm not sure) whether there is a stack walkback in
such cases, but from a quality of implementation point of view,
I think not walking back the stack is to be preferred.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jul 23 '08 #11
On Jul 22, 2:53 pm, Pete Becker <p...@versatilecoding.comwrote:
On 2008-07-22 06:29:01 -0400, Pep <pepaltavi...@yahoo.co.uksaid:
As to whether valgrind is simply wrong, that is another good
question that I had been toying with myself, yet loathe to
mention. It always seems easier to blame the tools ;)
Indeed. But in the case of memory testers, it's not uncommon
to get false positives for resources that are managed in
peculiar ways by the runtime library. Exception objects are
not like normal objects, and I wouldn't be surprised if memory
testers sometimes get them wrong.
More generally, there are really cases where "it depends".
Purify (but probably all of the others as well---I've just not
had the occasion to check) has options to allow masking certain
"errors", because they're intentional (e.g. you don't destruct a
singleton), but the tool has no way of knowing this.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jul 23 '08 #12
James Kanze <ja*********@gmail.comwrites:
On Jul 22, 11:40 pm, Juha Nieminen <nos...@thanks.invalidwrote:
>James Kanze wrote:
Of course, under a well behaved operating system, nothing
leaks, even if a process terminates abnormally.
>No OS can know if the program created some temporary files
which it intends to delete when it terminates.

Sure it can. Perhaps the most common OS's don't do this, but
they certainly could (and I've used at least one OS which did).
For that matter, it's possible to do so under Unix (but only to
a limited extent).
What limit do you see in:

char path[]="/tmp/myappl-XXXXXX";
int fd=mkstemp(path);
if(fd!=-1){
unlink(path);
}

knowing that unix systems implement a garbage collector over /tmp on
each reboot (and sometimes even more often), for the unlikely case
where the program crashes between the mkstemp call and the unlink
call.
--
__Pascal Bourguignon__
Jul 23 '08 #13
Pascal J. Bourguignon wrote:
What limit do you see in:
Other programs can't access it unless you smuggle the open file
descriptor over a socket or something similarly arcane (if supported by
the OS in question).
Jul 23 '08 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

13
by: Roman Mashak | last post by:
Hello, All! I have this small piece of code, where segmentation fault happenes only upon runnin code. No problems during debug (JFI I'm using gdb-6.3): ---- struct host_info { char *host;...
8
by: ranjeet.gupta | last post by:
Dear All Is the Root Cause of the Memory corruption is the Memory leak, ?? suppose If in the code there is Memory leak, Do this may lead to the Memory Corruption while executing the program ? ...
17
by: José Joye | last post by:
Hi, I have implemented a Service that is responsible for getting messages from a MS MQ located on a remote machine. I'm getting memory leak from time to time (???). In some situation, it is...
4
by: Don Nell | last post by:
Hello Why is there a memory leak when this code is executed. for(;;) { ManagementScope scope = new ManagementScope(); scope.Options.Username="username"; scope.Options.Password="password";...
20
by: jeevankodali | last post by:
Hi I have an .Net application which processes thousands of Xml nodes each day and for each node I am using around 30-40 Regex matches to see if they satisfy some conditions are not. These Regex...
3
by: Emmanuel Gehin | last post by:
When I use the following code in VB.NET : Public Function test() As String Try Dim da1 As OdbcDataAdapter Dim i As Int32 Dim tfem As DataTable For i = 0 To 1000 da1 = New...
3
by: Jim Land | last post by:
Jack Slocum claims here http://www.jackslocum.com/yui/2006/10/02/3-easy-steps-to-avoid-javascript- memory-leaks/ that "almost every site you visit that uses JavaScript is leaking memory". ...
1
by: Joe Peterson | last post by:
I've been doing a lot of searching on the topic of one of Python's more disturbing issues (at least to me): the fact that if a __del__ finalizer is defined and a cyclic (circular) reference is...
7
by: Ragnar Agustsson | last post by:
Hi all I have been wandering about the best way to sandbox memory leaks in 3rd party libraries when using them from the .Net framework. I have a 3rd party library, written in C++, that leaks a...
22
by: Peter | last post by:
I am using VS2008. I have a Windows Service application which creates Crystal Reports. This is a multi theaded application which can run several reports at one time. My problem - there is a...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.