Boost logo

Boost :

Subject: Re: [boost] C++ announcements coming tomorrow
From: Stephan T. Lavavej (stl_at_[hidden])
Date: 2012-11-04 21:06:42


[Andrey Semashev]
> +1, I had reported a memory leak bug [1] to MS and had been told that
> the behavior is correct as it doesn't contradict the Standard. I can't
> trust the vendor that treats users this way and declares a memory leak
> as a valid behavior. I doubt I will ever bother reporting any other
> bugs in MSVC.
> [1] The leak appeared in STL streams, if initialized multiple times.
> Here's a code snippet:
> https://sourceforge.net/apps/trac/boost-log/ticket/2#comment:4
> I didn't keep a reference to the MS bug tracker and I can't find it now.

This was Dev10#831920/Connect#518512. I can't load the Connect link anymore (it is supposed to be http://connect.microsoft.com/VisualStudio/feedback/details/518512/memory-leak-in-ostream-init and I don't know why it's broken) but I can still see the comments through Team Foundation Server. This behavior was really, truly conformant to the Standard - I was surprised too, so I had to ask P.J. Plauger for an explanation. Here are the comments:

--
Posted by ildjarn on 12/7/2009 at 3:21 AM
Reproduced using VC++ 2010 beta 2. I traced the leak back to std::ios_base::_Init(), which effectively does the following (where _Ploc is a std::locale*): _Ploc = 0; // other code _Ploc = new locale; I would think that before assigning NULL to _Ploc, it should be doing 'delete _Ploc;'.
Posted by Microsoft on 12/7/2009 at 6:39 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Posted by Microsoft on 12/8/2009 at 10:36 PM
Thanks for your feedback. We are rerouting this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue. Thank you
Posted by Microsoft on 12/9/2009 at 3:11 PM
Hi, Thanks for reporting this issue. I've resolved it as By Design because section 27.4.4.1 [lib.basic.ios.cons] of the 2003 C++ Standard does not allow init() to be called on a constructed object. (Yes, this is strange.) If you have any further questions, feel free to E-mail me at stl_at_[hidden] . Stephan T. Lavavej Visual C++ Libraries Developer
Posted by AndySem on 12/9/2009 at 9:42 PM
Sorry, but what particular statement in the Standard leads to this conclusion? I did not find such a restriction in 27.4.4.1 (and in particular, in point 3, where init effects are described).
Posted by Microsoft on 12/10/2009 at 4:47 PM
See 27.4.4.1/2: basic_ios() "Constructs an object of class basic_ios (27.4.2.7) leaving its member objects uninitialized. The object must be initialized by calling its init member function. If it is destroyed before it has been initialized the behavior is undefined." Because init() is called when data members are uninitialized, it must assume that any pointers are garbage, and can't delete them. That's why it leaks memory when called on a fully initialized object. Stephan T. Lavavej Visual C++ Libraries Developer
Posted by AndySem on 12/10/2009 at 8:24 PM
First, this does not mean that init cannot be called more than once. Technically speaking, it may track whether it was called or not in an internal data member that is not covered by the Standard. Second, the Standard does not describe data members at all in the first place. It does not say that basic_ios shall have raw pointers instead of, say, auto_ptrs. The constructor cannot be called without default initializing these members. So the whole statement about "leaving its member objects uninitialized" is a moot and should be understood as "the members are default initialized and in that state the basic_ios object may not be usable". That is why I still consider it as a bug. I think it should be fixed.
Posted by Microsoft on 12/11/2009 at 1:24 PM
The Standard allows an implementation to provide very weak guarantees on when init() may be called; therefore, VC's implementation conforms to the Standard. Although we could probably provide stronger guarantees, strictly conforming programs couldn't take advantage of them. Our implementation (licensed from Dinkumware) has behaved this way for over 20 years, and given our finite resources we don't believe that changing our design here is worth the time necessary. (There are some places where we believe that exceeding the Standard's guarantees is worthwhile - e.g. we supported stateful allocators long before C++0x required it.) I know that this isn't what you want to hear, but this is why the Standard exists in the first place - to provide a contract between implementers and users, saying what implementers are required to provide and what users are allowed to depend on. If you would like the Standard to provide stronger guarantees, you can file a Library Issue with the Committee. Stephan T. Lavavej Visual C++ Libraries Developer
--
STL

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk