Thread: vector of std::string reported as leaks

  1. #1
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607

    vector of std::string reported as leaks

    I have a vector of std::string's in an engine console class for one of my games which is used as a log. The console is a singleton so it's cleaned up by the compiler.

    The debug CRT reports every logged message as leaked. Is this because the CRT does not see the singleton get 'deleted' since the compiler cleans it up automatically?

    It's quite annoying. I can't very well iterate through the vector and call delete on the strings since they are not pointers.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Put breakpoints on the dtor and on the leak report entry point.
    My guess is the leak report is called first.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Bubba View Post
    The debug CRT reports every logged message as leaked. Is this because the CRT does not see the singleton get 'deleted' since the compiler cleans it up automatically?
    That would be a fair guess: a practical definition of a leak is memory that your program explicitly allocates but does not explicitly deallocate.
    Quote Originally Posted by Bubba View Post
    It's quite annoying. I can't very well iterate through the vector and call delete on the strings since they are not pointers.
    The actual issue is probably the singleton being destructed after the leak is reported.

    I'm guessing your singleton is a static object: it is fairly common for leak detectors to introduce a static object as well (eg its destructor does the reporting). The basic problem is that the order of construction and destruction of static objects is implementation-defined so, without specific help from the compiler, it is impossible to guarantee that the object introduced to support the leak detect is constructed first (ie before your singleton) and destructed last (after your singleton).

    A common way to stop such leak detectors from moaning is to avoid reliance on order of construction, which normally means avoiding static objects (at least, ones that directly or indirectly manage resources - which a vector<string> does). That way, you have to write functions that explicitly initialises your singletons and destroy your singletons, and call both explicitly from main(). This ensures your singletons are destructed before main() returns .... and also means they are destroyed before any static objects, such as those involving the leak detector.

    I did see a more evil technique once, that involved the singleton intercepting data output by the leak detector, and removing references or reports related to objects managed by the singleton. I mention that in the interests of completeness; I don't offer it as a recommendation.
    Last edited by grumpy; 11-01-2008 at 05:40 PM.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Every time I try to delete a singleton instance I get major issues. Most of the time it throws.

    Put breakpoints on the dtor and on the leak report entry point.
    I'm not sure where the entry point is. I'm not specifically calling for the report other than setting up the CRT so that it auto detects and auto reports.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Just a thought, but if you run a memory leak detector, does it report any leaks?
    If it does not, then it probably is a false alarm, and it would be nice to have that confirmed, at the very least.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Bubba View Post
    Every time I try to delete a singleton instance I get major issues. Most of the time it throws.
    Without code, it's hard to comment on that, but the #1 cause of problems in a destructor (eg throwing faults when deleting an object) is almost certainly a pointer molestation somewhere else.

    To preach the obvious to the converted .... provide a small but complete sample of code that exhibits your problem .....

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Code:
    class Console
    {
           public:
            static void createInstance();
            static Console* getInstance();
    
            ...
            ...
        
        private:
            Console();
            virtual ~Console();
            Console(const Console &obj);
            Console& operator = (const Console &obj);
            std::list<std::string> m_Messages;
            ...   
            ...
            
    };
    That's about all that needs shown. createInstance() is called during setup() which is called from the main process. After that getInstance() is used. Upon shutdown the destructor calls clear on m_Messages. Fairly straightforward, somewhat modified, singleton pattern.

  8. #8
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I think I found the problem. Before outputting the messages to the vector log I use ostringstream to create the final string complete with date and time stamp. I think my VS 2005 is pre-SP1 which means there is a definite leak in std::stringstream.

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    The destruction of the singleton after reporting of memory leaks seems to be a very likely problem (it is pretty common). Did you solve that or rule it out or verify that it is a problem?

  10. #10
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    It's both and. Stringstream is leaking and the strings are also reported as leaks. It's something I can ignore since the singleton is cleaned up after the mem leak report.

  11. #11
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Bubba View Post
    Upon shutdown the destructor calls clear on m_Messages.
    Why?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Bubba View Post
    It's both and. Stringstream is leaking and the strings are also reported as leaks. It's something I can ignore since the singleton is cleaned up after the mem leak report.
    Have you confirmed that? I mentioned it as a possible explanation to be chased down.

  13. #13
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Yeah I switched the container to char * and then added a cleanup function and called it before the singleton died. The cleanup iterated the container and cleaned up the memory. This stopped the string leaks.

  14. #14
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I thought the string wasn't leaking, it was just getting destroyed after the memory leak detection was run?

    If so, then changing to char*'s (especially in a vector) seems like a lot of risk for a non-problem. Is it really that big of a deal that you're getting false leaks reported when you know that they aren't really leaks?

  15. #15
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Since every logged message in the console is reported it is sort of a big deal and a major annoyance.

    I thought the string wasn't leaking, it was just getting destroyed after the memory leak detection was run?
    It's not but I cannot clean them up early either. I've tried clear() on the list in a Console::cleanup() function to no avail. So I figured I would force the list into being char * and use std::string.c_str() to place the strings into the list. It seems to have cleaned up the leak reporting.
    Last edited by VirtualAce; 11-05-2008 at 08:06 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 07:54 AM
  2. Replies: 13
    Last Post: 12-14-2007, 03:34 PM
  3. Improving my code
    By rwmarsh in forum C++ Programming
    Replies: 14
    Last Post: 07-08-2006, 11:18 AM
  4. Debugging help
    By cuddlez.ini in forum C++ Programming
    Replies: 3
    Last Post: 10-24-2004, 07:08 PM
  5. DLL and std::string woes!
    By Magos in forum C++ Programming
    Replies: 7
    Last Post: 09-08-2004, 12:34 PM