string/stringstream memory management

Discussion in 'C++' started by Ellarco, Sep 24, 2003.

  1. Ellarco

    Ellarco Guest

    Im sorry for asking a question that is surely in the archives somewhere, but
    I have been unable to locate it.

    Its about string memory management. I need to dynamically construct a
    C-style string and was planning to go about it this way;

    char* foo()
    {
    std::stringstream ss;
    ss << ...
    std::string s = ss.str();
    char* c = s.c_str();
    return c;
    }

    void main()
    {
    char* c = foo();
    // work with c
    delete(c);
    }

    What am I doing wrong? Should I be deleting stuff somewhere? Will the foo
    return a pointer to some out of scope memory - should it be;

    char* foo()
    {
    std::stringstream* ss = new std::stringstream();
    *ss << ...
    std::string s = ss->str();
    delete(ss);
    char* c = s.c_str();
    return c;
    }

    Am I deleting too much? ...

    Thanks for any guidance you can offer.

    El.
     
    Ellarco, Sep 24, 2003
    #1
    1. Advertising

  2. Ellarco wrote:
    > Im sorry for asking a question that is surely in the archives somewhere, but
    > I have been unable to locate it.


    This one is a classic -

    >
    > Its about string memory management. I need to dynamically construct a
    > C-style string and was planning to go about it this way;


    That usually means use of new

    >
    > char* foo()
    > {
    > std::stringstream ss;

    ^^^^ defined automatic - life of object is life of function
    > ss << ...
    > std::string s = ss.str();

    ^^^^ defined automatic - life of object is life of function
    > char* c = s.c_str();

    ^^^^ s.c_str() did not copy or allocate new memory for this
    > return c;

    ^^^^ Oops - returning a pointer to memory that is just about to be
    deleted ...

    > }
    >
    > void main()
    > {
    > char* c = foo();

    ^^^^ c is pointing to memory that is unallocated
    > // work with c
    > delete(c);

    ^^^^ trying to deallocate a pointer that is not allocated bad bad bad
    > }
    >
    > What am I doing wrong? Should I be deleting stuff somewhere? Will the foo
    > return a pointer to some out of scope memory - should it be;
    >
    > char* foo()
    > {
    > std::stringstream* ss = new std::stringstream();
    > *ss << ...
    > std::string s = ss->str();
    > delete(ss);

    ^^^^ It's not your responsibility to delete this, s will do it when it
    gets destroyed.
    > char* c = s.c_str();
    > return c;
    > }
    >
    > Am I deleting too much? ...


    YEP.


    >
    > Thanks for any guidance you can offer.
    >
    > El.
     
    Gianni Mariani, Sep 24, 2003
    #2
    1. Advertising

  3. Ellarco

    Ron Natalie Guest

    "Ellarco" <> wrote in message news:...


    > char* c = s.c_str();


    First, this shouldn't even compile. c_str() is returns const char*.

    The return value of c_str() becomes invalid as soon as a non-const member
    (including the destructor), get's invoked. S is destroyed as soon as the
    function exits so the value returned is invalid by the time it reaches the
    caller.

    You could return a copy.
    char* c = new char[s.size()+1];
    strcpy(c, s.c_str());
    return c;

    > void main()


    main must return int.

    > delete(c);


    Delete is not a function. You don't need the parens. Further,
    Since your intent is that c points to an array allocation, the proper
    delete is:
    delete [] c;

    > std::stringstream* ss = new std::stringstream();
    > *ss << ...
    > std::string s = ss->str();
    > delete(ss);


    This is just an elaborate way of doing the same thing you had before.
    It's not the stringstream that was the problem, it was what you did with
    the string called "s" afterwoard.

    Why not just return a string. It's usually easier when you need a const char*
    out of a string to just use c_str() at the last possible moment. Frequently, the
    lifetime of ths string is such that you don't have to wory about making a copy
    of the c_str() value because your string persists longer than the char* is needed.
     
    Ron Natalie, Sep 24, 2003
    #3
  4. (Ellarco) writes:

    > Im sorry for asking a question that is surely in the archives somewhere, but
    > I have been unable to locate it.
    >
    > Its about string memory management. I need to dynamically construct a
    > C-style string and was planning to go about it this way;
    >
    > char* foo()
    > {
    > std::stringstream ss;


    use std::eek:stringstream

    > ss << ...
    > std::string s = ss.str();
    > char* c = s.c_str();
    > return c;
    > }


    here, s goes out of scope and is destroyed - c points to never-neverland.

    > void main()


    main returns int

    > {
    > char* c = foo();
    > // work with c
    > delete(c);
    > }


    You can either create a new C-style string in foo() using strcpy(), or
    you can (much preferable IMHO) just return a std::string from foo:

    std::string foo() {
    std::eek:stringstream ss;
    ss << ...;
    return ss.str();
    }

    If you insist on using C-style strings, create one with new[] in
    foo, strcpy() to it, and delete[] it in main().

    HTH & kind regards
    frank

    --
    Frank Schmitt
    4SC AG phone: +49 89 700763-0
    e-mail: frankNO DOT SPAMschmitt AT 4sc DOT com
     
    Frank Schmitt, Sep 24, 2003
    #4
  5. Ellarco wrote:
    >
    > Im sorry for asking a question that is surely in the archives somewhere, but
    > I have been unable to locate it.
    >
    > Its about string memory management. I need to dynamically construct a
    > C-style string and was planning to go about it this way;
    >
    > char* foo()
    > {
    > std::stringstream ss;
    > ss << ...
    > std::string s = ss.str();
    > char* c = s.c_str();
    > return c;
    > }
    >


    Bad idea.
    AT the moment this function terminates, the object s is killed.
    And since the object s is killed, so is the buffer it handed out
    to you through c_str().


    > void main()


    int main()

    > {
    > char* c = foo();
    > // work with c
    > delete(c);


    wrong syntax. Must be delete [] c;
    Please: always cut and paste code, don't write it directly in your
    newsreader. Otherwise we are hunting bugs which simply are not there
    in your real program.

    Well. Did you allocate something? Did your documentation of c_str()
    tell you to delete the buffer?
    The answer is no in both cases. So, no, you don't have to delete
    anything (but that will change in a short while :)

    As you have seen, you can't return what c_str() gives to you, since
    the object itself goes out of scope and hence the buffer is deleted,
    while doing so. From this it follows that you first have to create
    a copy of the C-style string:

    char* foo()
    {
    ....
    std::string s = ss.str();

    char* c = new char [ s.size() + 1 ];
    strcpy( c, s.c_str() );
    return c;
    }

    Now foo hands out a dynamically allocated buffer which is filled with
    a copy of what c_str() handed out.
    And since this buffer was allocated with new[], you have to delete[]
    it somewhere.

    int main()
    {
    char* cc = foo();
    ....
    delete [] c;
    }

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Sep 24, 2003
    #5
  6. Ellarco

    Ellarco Guest

    "Karl Heinz Buchegger" <> wrote in message
    news:...
    >
    >
    > Ellarco wrote:
    > >
    > > Im sorry for asking a question that is surely in the archives somewhere,

    but
    > > I have been unable to locate it.
    > >
    > > Its about string memory management. I need to dynamically construct a
    > > C-style string and was planning to go about it this way;
    > >
    > > char* foo()
    > > {
    > > std::stringstream ss;
    > > ss << ...
    > > std::string s = ss.str();
    > > char* c = s.c_str();
    > > return c;
    > > }
    > >

    >
    > Bad idea.
    > AT the moment this function terminates, the object s is killed.
    > And since the object s is killed, so is the buffer it handed out
    > to you through c_str().
    >
    >
    > > void main()

    >
    > int main()
    >
    > > {
    > > char* c = foo();
    > > // work with c
    > > delete(c);

    >
    > wrong syntax. Must be delete [] c;
    > Please: always cut and paste code, don't write it directly in your
    > newsreader. Otherwise we are hunting bugs which simply are not there
    > in your real program.
    >
    > Well. Did you allocate something? Did your documentation of c_str()
    > tell you to delete the buffer?
    > The answer is no in both cases. So, no, you don't have to delete
    > anything (but that will change in a short while :)
    >
    > As you have seen, you can't return what c_str() gives to you, since
    > the object itself goes out of scope and hence the buffer is deleted,
    > while doing so. From this it follows that you first have to create
    > a copy of the C-style string:
    >
    > char* foo()
    > {
    > ....
    > std::string s = ss.str();
    >
    > char* c = new char [ s.size() + 1 ];
    > strcpy( c, s.c_str() );
    > return c;
    > }
    >
    > Now foo hands out a dynamically allocated buffer which is filled with
    > a copy of what c_str() handed out.
    > And since this buffer was allocated with new[], you have to delete[]
    > it somewhere.
    >
    > int main()
    > {
    > char* cc = foo();
    > ....
    > delete [] c;
    > }
    >
    > --
    > Karl Heinz Buchegger
    >


    Thanks to all. Youve cleared it up. To summarise what youve said, everything
    is as normal. I had an idea in my head that string behaved in some sort of
    anomalas (in terms of memory) way - idiot. Apologies for the buggy code I
    posted, and thanks again.

    El.
     
    Ellarco, Sep 24, 2003
    #6
    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. Floris van Haaster

    Project management / bug management

    Floris van Haaster, Sep 23, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    1,243
    Jon Paal
    Sep 23, 2005
  2. pouet
    Replies:
    2
    Views:
    761
    Will Hartung
    Jul 30, 2004
  3. KidLogik
    Replies:
    2
    Views:
    7,879
    Alberto Barbati
    Feb 24, 2004
  4. Laco
    Replies:
    1
    Views:
    409
    mlimber
    Oct 20, 2006
  5. Matt Oefinger
    Replies:
    0
    Views:
    217
    Matt Oefinger
    Jun 25, 2003
Loading...

Share This Page