STL string, need to free the memory?

O

olan

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
 
M

Mirek Fidler

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
 
D

Dave Townsend

Mirek Fidler said:
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.
 
C

Cy Edmunds

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.
 
O

olan

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
 
T

Tom Felker

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, <[email protected]>
<http://vlevel.sourceforge.net> - Stop fiddling with the volume knob.

Try not! Do! or do not. There is no try.
-- Yoda
 
G

Greg

Tom said:
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."

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
 
H

hacker++

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?
 
G

Geo

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.
 
M

Mirek Fidler

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
 
P

P.J. Plauger

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
 
M

Mirek Fidler

P.J. Plauger said:
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
 
O

olan

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
 
J

Jeff Flinn

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
 
O

olan

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top