STL string, need to free the memory?

Discussion in 'C++' started by olan@freesurf.fr, Aug 14, 2005.

  1. Guest

    Hi
    I'm kinda new at this, but...

    I have a class with a STL string m_strText
    and a member function that sets the text :

    void CTest::SetString( char *pszText )
    {
    m_strText = pszText;
    }

    When my program exits, I have a memory leak that corresponds
    to the text in m_strText.

    Do I have to do something special to free up the memory?
    I didn't see any functions like that in the STL string docs.
    Thanks
    Fred

    PS this is with MSVC++ 6.0
    , Aug 14, 2005
    #1
    1. Advertising

  2. Mirek Fidler Guest

    wrote:
    > Hi
    > I'm kinda new at this, but...
    >
    > I have a class with a STL string m_strText
    > and a member function that sets the text :
    >
    > void CTest::SetString( char *pszText )
    > {
    > m_strText = pszText;
    > }
    >
    > When my program exits, I have a memory leak that corresponds
    > to the text in m_strText.
    >
    > Do I have to do something special to free up the memory?


    Make sure that you destroy CTest.

    Mirek
    Mirek Fidler, Aug 14, 2005
    #2
    1. Advertising

  3. "Mirek Fidler" <> wrote in message
    news:...
    > wrote:
    > > Hi
    > > I'm kinda new at this, but...
    > >
    > > I have a class with a STL string m_strText
    > > and a member function that sets the text :
    > >
    > > void CTest::SetString( char *pszText )
    > > {
    > > m_strText = pszText;
    > > }
    > >
    > > When my program exits, I have a memory leak that corresponds
    > > to the text in m_strText.
    > >
    > > Do I have to do something special to free up the memory?

    >
    > Make sure that you destroy CTest.
    >
    > Mirek


    It looks to me that the pszText is the guy who should be deleted, STL
    string will make a
    copy of the char* given to it.
    Dave Townsend, Aug 14, 2005
    #3
  4. Cy Edmunds Guest

    <> wrote in message
    news:...
    > Hi
    > I'm kinda new at this, but...
    >
    > I have a class with a STL string m_strText
    > and a member function that sets the text :
    >
    > void CTest::SetString( char *pszText )


    There's a lot to not like about this signature. First of all, it uses the
    dreaded Hungarian notation. (Of course if your workgroup uses it, nothing
    can be done.) Secondly, it doesn't change what pszText points to so the
    argument should be declared const. Thirdly, it is really more convenient to
    make the argument (const std::string &strText). If you do that, anybody who
    uses this function can still use a const char * because it will
    automatically be converted to a std::string. However, if somebody wants to
    use a std::string, say "s", he won't have to write
    my_CTest.SetString(s.c_str()); which takes a std::string, extracts a const
    char *, and converts it back to a std::string. ugh.

    > {
    > m_strText = pszText;
    > }
    >
    > When my program exits, I have a memory leak that corresponds
    > to the text in m_strText.


    Look elsewhere. std::string cleans up its own memory. If you got the string
    using operator new() you may not have made a corresponding call to operator
    delete(). If you created the CTest object with operator new(), the same
    problem may have arisen.

    >
    > Do I have to do something special to free up the memory?
    > I didn't see any functions like that in the STL string docs.
    > Thanks
    > Fred
    >
    > PS this is with MSVC++ 6.0
    >


    --
    Cy
    http://home.rochester.rr.com/cyhome/
    Cy Edmunds, Aug 15, 2005
    #4
  5. Guest

    Sorry about the Hungarian.... regarding const etc this is just a quick
    test program to try to find out where the leaks come from so I didnt
    strive for perfection.

    anyway the complete program is

    #include <windows.h>
    #include <crtdbg.h>
    #include "CTest.h"

    CTest Test;

    int main( int argc, char *argv[] )
    {
    std::string strBlabla;

    Test.SetString( "blabla" );
    strBlabla = Test.GetString();

    printf( "the string is %s\n", strBlabla.c_str() );

    _CrtDumpMemoryLeaks();
    return 0;
    }

    if I comment out the SetString call I have no leaks
    When the SetString call runs I have leaks
    This is a pretty simple program and yet I don't see where the leak
    could come from
    Thanks
    Fred
    , Aug 15, 2005
    #5
  6. Tom Felker Guest

    On Sun, 14 Aug 2005 20:37:03 -0700, olan wrote:

    > Sorry about the Hungarian.... regarding const etc this is just a quick
    > test program to try to find out where the leaks come from so I didnt
    > strive for perfection.
    >
    > anyway the complete program is
    >
    > #include <windows.h>
    > #include <crtdbg.h>
    > #include "CTest.h"
    >
    > CTest Test;
    >
    > int main( int argc, char *argv[] )
    > {
    > std::string strBlabla;
    >
    > Test.SetString( "blabla" );
    > strBlabla = Test.GetString();
    >
    > printf( "the string is %s\n", strBlabla.c_str() );
    >
    > _CrtDumpMemoryLeaks();
    > return 0;
    > }
    >
    > if I comment out the SetString call I have no leaks
    > When the SetString call runs I have leaks
    > This is a pretty simple program and yet I don't see where the leak
    > could come from
    > Thanks
    > Fred


    The strBlabla object's destructor (where it would deallocate its memory)
    doesn't get called until control passes out of the block in which it is
    declared, in this case, main(). If you move everything except the last
    two lines into a new function that main calls, then you won't call
    _CrtDumpMemoryLeaks until that new function returns, and thus, you
    shouldn't see the "leak."

    --
    Tom Felker, <>
    <http://vlevel.sourceforge.net> - Stop fiddling with the volume knob.

    Try not! Do! or do not. There is no try.
    -- Yoda
    Tom Felker, Aug 15, 2005
    #6
  7. Greg Guest

    Tom Felker wrote:
    > On Sun, 14 Aug 2005 20:37:03 -0700, olan wrote:
    >
    > > Sorry about the Hungarian.... regarding const etc this is just a quick
    > > test program to try to find out where the leaks come from so I didnt
    > > strive for perfection.
    > >
    > > anyway the complete program is
    > >
    > > #include <windows.h>
    > > #include <crtdbg.h>
    > > #include "CTest.h"
    > >
    > > CTest Test;
    > >
    > > int main( int argc, char *argv[] )
    > > {
    > > std::string strBlabla;
    > >
    > > Test.SetString( "blabla" );
    > > strBlabla = Test.GetString();
    > >
    > > printf( "the string is %s\n", strBlabla.c_str() );
    > >
    > > _CrtDumpMemoryLeaks();
    > > return 0;
    > > }
    > >
    > > if I comment out the SetString call I have no leaks
    > > When the SetString call runs I have leaks
    > > This is a pretty simple program and yet I don't see where the leak
    > > could come from
    > > Thanks
    > > Fred

    >
    > The strBlabla object's destructor (where it would deallocate its memory)
    > doesn't get called until control passes out of the block in which it is
    > declared, in this case, main(). If you move everything except the last
    > two lines into a new function that main calls, then you won't call
    > _CrtDumpMemoryLeaks until that new function returns, and thus, you
    > shouldn't see the "leak."
    >
    > --
    > Tom Felker, <>
    > <http://vlevel.sourceforge.net> - Stop fiddling with the volume knob.
    >


    Reasonable advice, but it probably won't get rid of the reported leak
    since we know there is a std::string data member (m_strText) in the
    CTest class. And since Test is a statically allocated CText object its
    m_strText data member won't be deallocated until after main exits, when
    Test is torn down.

    Greg
    Greg, Aug 15, 2005
    #7
  8. hacker++ Guest

    wrote:

    > anyway the complete program is
    >
    > #include <windows.h>
    > #include <crtdbg.h>
    > #include "CTest.h"
    >
    > CTest Test;
    >
    > int main( int argc, char *argv[] )
    > {


    //Add additional scope here
    {
    > std::string strBlabla;
    >
    > Test.SetString( "blabla" );
    > strBlabla = Test.GetString();
    >
    > printf( "the string is %s\n", strBlabla.c_str() );
    >


    // end of dummy scope
    }
    > _CrtDumpMemoryLeaks();
    > return 0;
    > }
    >


    Do you still get the leak?
    hacker++, Aug 15, 2005
    #8
  9. Geo Guest

    wrote:
    > Sorry about the Hungarian.... regarding const etc this is just a quick
    > test program to try to find out where the leaks come from so I didnt
    > strive for perfection.
    >
    > anyway the complete program is
    >
    > #include <windows.h>
    > #include <crtdbg.h>
    > #include "CTest.h"
    >
    > CTest Test;
    >
    > int main( int argc, char *argv[] )
    > {
    > std::string strBlabla;
    >
    > Test.SetString( "blabla" );
    > strBlabla = Test.GetString();
    >
    > printf( "the string is %s\n", strBlabla.c_str() );
    >
    > _CrtDumpMemoryLeaks();
    > return 0;
    > }
    >
    > if I comment out the SetString call I have no leaks
    > When the SetString call runs I have leaks
    > This is a pretty simple program and yet I don't see where the leak
    > could come from
    > Thanks
    > Fred


    I don't know about other compilers, but Visual C++ runs it's leak
    detection code before it destroys global objects, so all globals that
    allocate memory appear to leak, move the definiton of test into main
    and it should go away.
    Geo, Aug 15, 2005
    #9
  10. Mirek Fidler Guest

    > argument should be declared const. Thirdly, it is really more convenient to
    > make the argument (const std::string &strText). If you do that, anybody who
    > uses this function can still use a const char * because it will
    > automatically be converted to a std::string. However, if somebody wants to
    > use a std::string, say "s", he won't have to write
    > my_CTest.SetString(s.c_str()); which takes a std::string, extracts a const
    > char *, and converts it back to a std::string. ugh.


    OTOH, this might bloat the code by including constructor call machinery
    at each call to SetString. If you are going to use it mainly for
    character constants, this might be significant....

    In fact, it is really sad that for rather false reasons, C++ comitee
    accepted c_str nonsense over simple operator const char *().

    Mirek
    Mirek Fidler, Aug 15, 2005
    #10
  11. P.J. Plauger Guest

    "Mirek Fidler" <> wrote in message
    news:...

    >> argument should be declared const. Thirdly, it is really more convenient
    >> to make the argument (const std::string &strText). If you do that,
    >> anybody who uses this function can still use a const char * because it
    >> will automatically be converted to a std::string. However, if somebody
    >> wants to use a std::string, say "s", he won't have to write
    >> my_CTest.SetString(s.c_str()); which takes a std::string, extracts a
    >> const char *, and converts it back to a std::string. ugh.

    >
    > OTOH, this might bloat the code by including constructor call machinery at
    > each call to SetString. If you are going to use it mainly for character
    > constants, this might be significant....
    >
    > In fact, it is really sad that for rather false reasons, C++ comitee
    > accepted c_str nonsense over simple operator const char *().


    Yep, because we quuickly learned that adding the const char *() cast caused
    all sorts of ambiguities. Better the nonsense that works than the elegance
    that doesn't.

    P.J. Plauger
    Dinkumware, Ltd.
    http://www.dinkumware.com
    P.J. Plauger, Aug 15, 2005
    #11
  12. Mirek Fidler Guest

    P.J. Plauger wrote:
    > "Mirek Fidler" <> wrote in message
    > news:...
    >
    >
    >>>argument should be declared const. Thirdly, it is really more convenient
    >>>to make the argument (const std::string &strText). If you do that,
    >>>anybody who uses this function can still use a const char * because it
    >>>will automatically be converted to a std::string. However, if somebody
    >>>wants to use a std::string, say "s", he won't have to write
    >>>my_CTest.SetString(s.c_str()); which takes a std::string, extracts a
    >>>const char *, and converts it back to a std::string. ugh.

    >>
    >>OTOH, this might bloat the code by including constructor call machinery at
    >>each call to SetString. If you are going to use it mainly for character
    >>constants, this might be significant....
    >>
    >>In fact, it is really sad that for rather false reasons, C++ comitee
    >>accepted c_str nonsense over simple operator const char *().

    >
    >
    > Yep, because we quuickly learned that adding the const char *() cast caused
    > all sorts of ambiguities. Better the nonsense that works than the elegance
    > that doesn't.


    Ambiguities can be easily sorted out. I am using string-like class(es)
    with this operator for more than decade and have not noticed any real
    problem here.

    Maybe it was testimony of the quality of C++ compilers (overloading
    rules) before 1998? :)

    Mirek
    Mirek Fidler, Aug 15, 2005
    #12
  13. Guest

    Thanks all. But, not solved yet!
    If the leak was due to the global object not having been destroyed yet,
    I should always get a leak even if I don't call SetString. That is not
    the case.

    To be sure, I removed the global object and now I have this:

    #include <windows.h>
    #include <crtdbg.h>
    #include "CTest.h"

    int main( int argc, char *argv[] )
    {
    std::string strBlabla;
    CTest *pTest;

    pTest = new CTest;

    pTest->SetString( "blabla" );
    strBlabla = pTest->GetString();

    printf( "the string is %s\n", strBlabla.c_str() );

    delete pTest;

    _CrtDumpMemoryLeaks();
    return 0;
    }

    Same behavior:
    if i call SetString, there's a leak. If I comment it out, no leak.
    For the sake of completness, here's the dump:
    Detected memory leaks!
    Dumping objects ->
    {44} normal block at 0x00430030, 33 bytes long.
    Data: < blabla > 00 62 6C 61 62 6C 61 00 CD CD CD CD CD CD CD
    CD
    Object dump complete.

    and the CTest class:

    ==== CTest.h
    #include <string>

    class CTest
    {
    public:
    void SetVal( UINT val );
    void SetString( char *pszText );
    std::string GetString();
    private:
    std::string m_strBlabla;
    UINT m_Val;
    };

    ==== CTest.cpp
    #include <windows.h>
    #include "CTest.h"

    void CTest::SetVal( UINT val )
    {
    m_Val = val;
    }

    void CTest::SetString( char *pszText )
    {
    m_strBlabla = pszText;
    }

    std::string CTest::GetString()
    {
    return m_strBlabla;
    }

    I really appreciate your help on this I have no clue what's going on!
    Fred
    , Aug 15, 2005
    #13
  14. Jeff Flinn Guest

    <> wrote in message
    news:...
    > Thanks all. But, not solved yet!
    > If the leak was due to the global object not having been destroyed yet,
    > I should always get a leak even if I don't call SetString.


    Why do you think that? The compiler supplied default constructor for CTest
    default constructs the std::string CTest::m_strBlabla, which does not
    allocate any memory.

    Jeff Flinn

    > That is not
    > the case.
    >
    > To be sure, I removed the global object and now I have this:
    >
    > #include <windows.h>
    > #include <crtdbg.h>
    > #include "CTest.h"
    >
    > int main( int argc, char *argv[] )
    > {
    > std::string strBlabla;
    > CTest *pTest;
    >
    > pTest = new CTest;
    >
    > pTest->SetString( "blabla" );
    > strBlabla = pTest->GetString();
    >
    > printf( "the string is %s\n", strBlabla.c_str() );
    >
    > delete pTest;
    >
    > _CrtDumpMemoryLeaks();


    strBlaBla still exist here.


    > return 0;
    > }


    strBlaBla is destroyed here.


    > Same behavior:
    > if i call SetString, there's a leak. If I comment it out, no leak.
    > For the sake of completness, here's the dump:
    > Detected memory leaks!
    > Dumping objects ->
    > {44} normal block at 0x00430030, 33 bytes long.
    > Data: < blabla > 00 62 6C 61 62 6C 61 00 CD CD CD CD CD CD CD
    > CD
    > Object dump complete.
    >
    > and the CTest class:
    >
    > ==== CTest.h
    > #include <string>
    >
    > class CTest
    > {
    > public:
    > void SetVal( UINT val );
    > void SetString( char *pszText );
    > std::string GetString();
    > private:
    > std::string m_strBlabla;
    > UINT m_Val;
    > };
    >
    > ==== CTest.cpp
    > #include <windows.h>
    > #include "CTest.h"
    >
    > void CTest::SetVal( UINT val )
    > {
    > m_Val = val;
    > }
    >
    > void CTest::SetString( char *pszText )
    > {
    > m_strBlabla = pszText;
    > }
    >
    > std::string CTest::GetString()
    > {
    > return m_strBlabla;
    > }
    >
    > I really appreciate your help on this I have no clue what's going on!



    Jeff Flinn
    Jeff Flinn, Aug 15, 2005
    #14
  15. Guest

    Jeff,

    I must be stupid.
    I was so focused on that string IN the class that I completely
    overlooked
    that other string. Indeed that leak comes from where you said.

    Thanks
    Fred
    , Aug 16, 2005
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kathy
    Replies:
    4
    Views:
    4,353
    David Rubin
    Sep 30, 2003
  2. Replies:
    8
    Views:
    1,913
    Csaba
    Feb 18, 2006
  3. Panduranga Chary

    How memory function free() knows how much memory to free.

    Panduranga Chary, Dec 27, 2007, in forum: C Programming
    Replies:
    2
    Views:
    413
    Keith Thompson
    Dec 27, 2007
  4. george
    Replies:
    0
    Views:
    1,108
    george
    Aug 29, 2008
  5. mohammed_a_o
    Replies:
    0
    Views:
    269
    mohammed_a_o
    Nov 30, 2010
Loading...

Share This Page