std::string and char pointers

Discussion in 'C++' started by Espen Ruud Schultz, Jul 18, 2003.

  1. Lets say I have a char pointer and an std::string. Is it possible to get a
    pointer to the std::string's "content" so that the char pointer can point to
    the same text? And vice versa; can I give the std::string a pointer and a
    length and then give the std::string control over the pointer and its
    content?

    I'm basically trying to avoid copying large text between an std::string and
    a char pointer, and vice versa.

    Is there anyhing in the std::string class to support this?

    , Espen
     
    Espen Ruud Schultz, Jul 18, 2003
    #1
    1. Advertising

  2. Espen Ruud Schultz wrote:
    > Lets say I have a char pointer and an std::string. Is it possible to get a
    > pointer to the std::string's "content" so that the char pointer can point to
    > the same text?


    Yes. Read about 'std::string::c_str()' method. But in any case,
    'std::string' will not hand over control of the stored string to the
    char pointer. 'std::string' will retain full control of the stored
    string and may invalidate the pointer returned by a previous call to
    'c_str()'.

    > And vice versa; can I give the std::string a pointer and a
    > length and then give the std::string control over the pointer and its
    > content?


    No. 'std::string' will make a copy.

    > I'm basically trying to avoid copying large text between an std::string and
    > a char pointer, and vice versa.


    The best strategy in this case is to use 'std::string' alone and try to
    avoid using strings "owned" by char pointers.

    --
    Best regards,
    Andrey Tarasevich
    Brainbench C and C++ Programming MVP
     
    Andrey Tarasevich, Jul 18, 2003
    #2
    1. Advertising

  3. Espen Ruud Schultz

    John Dibling Guest

    On Fri, 18 Jul 2003 13:22:09 -0700, Andrey Tarasevich
    <> wrote:

    >Espen Ruud Schultz wrote:
    >> Lets say I have a char pointer and an std::string. Is it possible to get a
    >> pointer to the std::string's "content" so that the char pointer can point to
    >> the same text?

    >
    >Yes. Read about 'std::string::c_str()' method. But in any case,


    No! Sure you can get a char const* from a string, but it's not
    guaranteed to be any good after youv'e used it. If you use c_str(),
    you have to use that pointer right away, then throw it away. If you
    try to save the pointer and use it later, you *could* have a wild
    pointer.

    Long story short, you need to deep-copy the string. Why do you want a
    char* to point to a std::string buffer anyway? Duplication of data is
    *usually* a bug.

    21.3.6.2 states:

    Requires: [snip] Nor shall the p[rogram treat the retuned valuie as a
    valid pointer value after any subsequent call to a non-const
    function... [snip]

    >> And vice versa; can I give the std::string a pointer and a
    >> length and then give the std::string control over the pointer and its
    >> content?

    >
    >No. 'std::string' will make a copy.


    Right, but you could use an auto_ptr instead of a string.

    Just what is it you are trying to accomplish?

    </dib>

    John Dibling
    email: dib@substitute_my_full_last_name_here.com
    Witty banter omitted for your protection
     
    John Dibling, Jul 18, 2003
    #3
  4. On Fri, 18 Jul 2003 21:49:47 +0200, "Espen Ruud Schultz"
    <> wrote:

    >Lets say I have a char pointer and an std::string. Is it possible to get a
    >pointer to the std::string's "content" so that the char pointer can point to
    >the same text? And vice versa; can I give the std::string a pointer and a
    >length and then give the std::string control over the pointer and its
    >content?
    >
    >I'm basically trying to avoid copying large text between an std::string and
    >a char pointer, and vice versa.
    >
    >Is there anyhing in the std::string class to support this?
    >
    >, Espen
    >


    std::string.c_str()

    Olli
     
    Oliver Fleischmann, Jul 18, 2003
    #4
  5. John Dibling wrote:
    > ...
    >>> Lets say I have a char pointer and an std::string. Is it possible to get a
    >>> pointer to the std::string's "content" so that the char pointer can point to
    >>> the same text?

    >>
    >>Yes. Read about 'std::string::c_str()' method. But in any case,

    >
    > No! Sure you can get a char const* from a string, but it's not
    > guaranteed to be any good after youv'e used it.


    This doesn't make any sense. What is a "used pointer"? There is no such
    notion in C++. The pointer obtained from 'c_str()' may be used as many
    times as user wants as long as this pointer remains valid. The actions
    that invalidate this pointer are clearly described in the specification
    of C++ standard library. You actually quite it below.

    > If you use c_str(),
    > you have to use that pointer right away, then throw it away.


    There in so such things as "right away" and "throw away" in the
    specification of standard library. The period this pointer remains valid
    is unambiguously defined and depends on the behavior of the concrete
    program.

    > If you
    > try to save the pointer and use it later, you *could* have a wild
    > pointer.


    Yes, you could. Just like I said in my original message, 'std::string'
    doesn't relinquish control of the controlled sequence.

    > Long story short, you need to deep-copy the string. Why do you want a
    > char* to point to a std::string buffer anyway?


    There are circumstances when you need to deep copy a string and there
    are circumstances when you don't need to deep copy a string. It depends
    on concrete context.

    > Duplication of data is *usually* a bug.


    I don't understand what you are trying to say. After promoting data
    duplication for a while, you suddenly declare it to be a bug.

    > 21.3.6.2 states:
    >
    > Requires: [snip] Nor shall the p[rogram treat the retuned valuie as a
    > valid pointer value after any subsequent call to a non-const
    > function... [snip]


    Once again, why did you start response with "No!" and then went on to
    basically restate everything that I said in my previous message. Did you
    try to read what I said before replying?

    >>> And vice versa; can I give the std::string a pointer and a
    >>> length and then give the std::string control over the pointer and its
    >>> content?

    >>
    >>No. 'std::string' will make a copy.

    >
    > Right, but you could use an auto_ptr instead of a string.
    > ...


    Huh? Just how do you plan to use an 'auto_ptr' in this case?

    --
    Best regards,
    Andrey Tarasevich
    Brainbench C and C++ Programming MVP
     
    Andrey Tarasevich, Jul 18, 2003
    #5
  6. Espen Ruud Schultz

    John Dibling Guest

    On Fri, 18 Jul 2003 14:16:21 -0700, Andrey Tarasevich
    <> wrote:


    >Yes, you could. Just like I said in my original message, 'std::string'
    >doesn't relinquish control of the controlled sequence.



    You are absolutely right. I did not read the words "'std::string'
    will retain full control of the stored string and may invalidate the
    pointer returned by a previous call to 'c_str()'." in your original
    post due to careless reading, and I misunderstood your argument to be
    a faulty one. My humble apologies.

    </dib>

    John Dibling
    email: dib@substitute_my_full_last_name_here.com
    Witty banter omitted for your protection
     
    John Dibling, Jul 18, 2003
    #6
  7. Thanx guys! I'm replying to my own post for several reason, one of them is
    to "start over" so to speak...

    Anyway, I knew about c_str() but I thought there was another way that didn't
    use zero termination. The reson why I needed it not to be zero terminated
    was trivial, and after I thought about it, non-existing. So to pop that out
    of this subject, c_str() is the way to get a pointer.

    Though getting a pointer to the content isn't the main thing I want, but
    giving a pointer to an std::string and just say "Here, take this pointer and
    the text it points to. This is yours. From now on I want to deal with this
    text through you."

    This is the abstract of what I'm trying to do, and the reason is simple: I
    read a text file from disk and into memory. The function that reads the
    file is unimportant, the only thing that matters is that it take a pointer
    to an already allocated space in memory. The file in question can be big,
    or it can be huge. Either way, I find it unnecessary to have to copy the
    text to get it into an std::string object. And since internally,
    std::string do keep a single pointer to its content, why not just tell
    std::string it can use an existing pointer? That way I don't have to copy
    the actual text...

    So is there any way for me to give an std::string object an existing pointer
    and have the std::string use that pointer exclusively? Though I standard
    way to go about this would be best, I really don't care. However, I do not
    wish to derive a new class from std::string just for this, and I really just
    hope there is a "proper" way to do this...

    , Espen
     
    Espen Ruud Schultz, Jul 18, 2003
    #7
  8. Espen Ruud Schultz wrote:

    > Thanx guys! I'm replying to my own post for several reason, one of them
    > is to "start over" so to speak...
    >
    > Anyway, I knew about c_str() but I thought there was another way that
    > didn't
    > use zero termination. The reson why I needed it not to be zero terminated
    > was trivial, and after I thought about it, non-existing. So to pop that
    > out of this subject, c_str() is the way to get a pointer.


    Zero-termination really has nothing to do with it... You want a pointer
    to the string's internal representation so you can modify it, yes?
    You want to be able to say something like
    read_file("foo.txt", my_string.get_internal_buffer());
    Right?
    That's not how strings work. You can't get that kind of access to the
    internals of a string.

    You have two options. (a) Copy the text from char* to std::string or (b)
    rewrite the function that reads in the file.

    --
    It isn't that unix isn't a user friendly operating system,
    it's just choosy about which users it wants to be friends
    with, and even the best of friends occasionally fight.
     
    Jacques Labuschagne, Jul 18, 2003
    #8
  9. Espen Ruud Schultz

    Jim Fischer Guest

    Espen Ruud Schultz wrote:
    > Lets say I have a char pointer and an std::string. Is it possible to get a
    > pointer to the std::string's "content" so that the char pointer can point to
    > the same text? And vice versa; can I give the std::string a pointer and a
    > length and then give the std::string control over the pointer and its
    > content?
    >
    > I'm basically trying to avoid copying large text between an std::string and
    > a char pointer, and vice versa.
    >
    > Is there anyhing in the std::string class to support this?


    If I understand your question correctly, I think the answer is "no".

    Comment 1) IIRC, there is no standard way to obtain a char* pointer to
    the actual "guts" of a std::string object.

    [n.b. If you invoke the std::string object's c_str() method, the method
    returns a pointer to a const-valued (unmodifiable) char array whose
    contents "match" the contents of the std::string object. Note that the
    returned pointer becomes invalid "after any subsequent call to a
    non-const member function of the class basic_string that designates the
    same object as this." [See: 21.3.6/2] For example:
    std::string s("hello");
    const char *p = s.c_str();
    s += '*'; // modifying 's' invalidates the address in 'p'
    // 'p' is now invalid
    ]


    Comment 2) AFAIK, the std::string class is not designed to use an
    existing char array as the "guts" of a std::string object. IOW, the
    contents of the existing char array are copied into the "guts" of the
    std::string object.

    --
    Jim

    To reply by email, remove "link" and change "now.here" to "yahoo"
    jfischer_link5809{at}now.here.com
     
    Jim Fischer, Jul 18, 2003
    #9
  10. "Jacques Labuschagne" <> wrote in message
    news:3111839.KXdPFfGyGt@klesk
    > Espen Ruud Schultz wrote:
    >
    >> Thanx guys! I'm replying to my own post for several reason, one of them
    >> is to "start over" so to speak...
    >>
    >> Anyway, I knew about c_str() but I thought there was another way that
    >> didn't
    >> use zero termination. The reson why I needed it not to be zero
    >> terminated was trivial, and after I thought about it, non-existing. So
    >> to pop that out of this subject, c_str() is the way to get a pointer.

    >
    > Zero-termination really has nothing to do with it... You want a pointer
    > to the string's internal representation so you can modify it, yes?
    >


    No, I don't. I want a pointer to the std::string's internal representation
    so I can read it. Excuse me for being rude, but I already said that the
    part about getting the pointer was done with...

    >
    > You want to be able to say something like
    > read_file("foo.txt", my_string.get_internal_buffer());
    > Right?
    >


    Nope, wrong again. I want to be able to do something like:

    read( "foo.txt", PointerToChar );
    String.UseThisPointer( PointerToChar, SizeInformationHere );

    , Espen
     
    Espen Ruud Schultz, Jul 18, 2003
    #10
  11. Espen Ruud Schultz wrote:

    > "Jacques Labuschagne" <> wrote in message
    > Nope, wrong again. I want to be able to do something like:
    >
    > read( "foo.txt", PointerToChar );
    > String.UseThisPointer( PointerToChar, SizeInformationHere );
    >


    As others have said, it can't be done.

    --
    To err is human. To forgive is not our policy.
    -- MIT Assassins Guild
     
    Jacques Labuschagne, Jul 18, 2003
    #11
  12. "Jacques Labuschagne" <> wrote in message
    news:1874502.j6fyHt1I0n@klesk
    > Espen Ruud Schultz wrote:
    >
    >> "Jacques Labuschagne" <> wrote in message
    >> Nope, wrong again. I want to be able to do something like:
    >>
    >> read( "foo.txt", PointerToChar );
    >> String.UseThisPointer( PointerToChar, SizeInformationHere );
    >>

    >
    > As others have said, it can't be done.
    >


    Yeah, sometimes I find the standard nothing more than limiting. Lots of
    "safe guards" and "proper ways". Bah, I'm just annoyed. Thanx though...

    , Espen
     
    Espen Ruud Schultz, Jul 19, 2003
    #12
  13. Espen Ruud Schultz

    Andre Kostur Guest

    "Espen Ruud Schultz" <> wrote in news:v1%Ra.7185
    $:

    > "Jacques Labuschagne" <> wrote in message
    > news:1874502.j6fyHt1I0n@klesk
    >> Espen Ruud Schultz wrote:
    >>
    >>> "Jacques Labuschagne" <> wrote in message
    >>> Nope, wrong again. I want to be able to do something like:
    >>>
    >>> read( "foo.txt", PointerToChar );
    >>> String.UseThisPointer( PointerToChar, SizeInformationHere );
    >>>

    >>
    >> As others have said, it can't be done.
    >>

    >
    > Yeah, sometimes I find the standard nothing more than limiting. Lots

    of
    > "safe guards" and "proper ways". Bah, I'm just annoyed. Thanx

    though...

    Well, it's only a matter of using the tool the way it's designed. One
    problem with your suggestion is that std::string would have no way of
    knowing _how_ that buffer was allocated. It could have been allocated
    with new, or it could be a local variable, or it could be a pointer to a
    string literal, or.... etc.

    As a result std::string wouldn't know what operations are possible on
    that buffer. As an example, if you passed it a pointer to a string
    literal, your program may explode when you tried to modify one of the
    characters later.

    A second example problem is that your buffer may have been allocated
    using a custom allocator of some sort (perhaps it's allocating from some
    sort of shared memory), std::string wouldn't know how to deallocate it.
     
    Andre Kostur, Jul 19, 2003
    #13
  14. Espen Ruud Schultz

    Stephen Howe Guest

    >So to pop that out of this subject, c_str() is the way to get a pointer.

    Not the only way. data() will do so as well without appenidng a terminating
    0.

    Stephen Howe
     
    Stephen Howe, Jul 19, 2003
    #14
  15. Espen Ruud Schultz

    Jon Bell Guest

    In article <Ev_Ra.511$2.webusenet.com>,
    Jim Fischer <> wrote:
    >Espen Ruud Schultz wrote:
    >>
    >> I'm basically trying to avoid copying large text between an std::string and
    >> a char pointer, and vice versa.
    >>
    >> Is there anyhing in the std::string class to support this?

    >
    >If I understand your question correctly, I think the answer is "no".
    >
    >Comment 1) IIRC, there is no standard way to obtain a char* pointer to
    >the actual "guts" of a std::string object.


    I think the "guts" are implementation-dependent anyway. The internal
    representation of std::string data might be something simple like a
    dynamically allocated array of char, or it might be something more
    complicated that is optimized for dealing with large strings, depending on
    whose version of the standard library you're using.

    --
    Jon Bell <> Presbyterian College
    Dept. of Physics and Computer Science Clinton, South Carolina USA
     
    Jon Bell, Jul 19, 2003
    #15
  16. "Espen Ruud Schultz" <> wrote in message
    news:daYRa.7149$...
    > Lets say I have a char pointer and an std::string. Is it possible to get

    a
    > pointer to the std::string's "content" so that the char pointer can point

    to
    > the same text? And vice versa; can I give the std::string a pointer and a
    > length and then give the std::string control over the pointer and its
    > content?
    >
    > I'm basically trying to avoid copying large text between an std::string

    and
    > a char pointer, and vice versa.
    >
    > Is there anyhing in the std::string class to support this?
    >
    > , Espen
    >


    If you want to be fast and loose try this

    string buf(10000);
    my_func(&buf[0]);

    Strictly illegal but if your string implementation uses contiguous memory
    then it may well work.

    Another option would be to replace string with vector<char> when the above
    really would work.

    john
     
    John Harrison, Jul 19, 2003
    #16
  17. "Stephen Howe" <> wrote in message
    news:3f18a138$0$961$
    >> So to pop that out of this subject, c_str() is the way to get a pointer.

    >
    > Not the only way. data() will do so as well without appenidng a
    > terminating 0.
    >


    Hmm, this makes me wonder. Are you sure data() doesn't have a zero in the
    end? If both c_str() and data() return pointers to the internal text, then
    if one of them don't have a zero and the other have one, then std::string
    must copy and keep at least two versions of its content when someone call
    either c_str() or data()...?

    It seems like the best way to deal with this is that std::string only keep
    one copy of its content and always have a zero termination at the end...

    , Espen
     
    Espen Ruud Schultz, Jul 19, 2003
    #17
  18. Espen Ruud Schultz wrote:
    > I find these problems to be trivial. Of course you have to know your
    > std::string and code accordingly...


    But the standard does not mandate any particular implementation, only the
    interface to the implementation. You are of course free to learn the
    internals from scratch for each new standard library implementation you
    use, provided that those details are available.
    It would perhaps be an illuminating experience were you to attempt an
    implementation of std::string...

    --
    The tube is civilization.
     
    Jacques Labuschagne, Jul 19, 2003
    #18
  19. Espen Ruud Schultz

    John Dibling Guest

    On Sat, 19 Jul 2003 00:09:08 +0200, "Espen Ruud Schultz"
    <> wrote:

    > the only thing that matters is that it take a pointer
    >to an already allocated space in memory.


    Can't be done; std::string isn't a smart pointer. But, you can
    reserve() space in the string, then call your function using
    string.begin(). This will look to your function like a plain char*,
    and you wont have to allocate a special temporary buffer. I believe I
    saw this method in Meyers' Effective STL, if anybody would like to
    look it up.

    >std::string do keep a single pointer to its content, why not just tell
    >std::string it can use an existing pointer? That way I don't have to copy
    >the actual text...


    Because std::string isn't a smart pointer, but you are trying to use
    it as if it were. If you really want a smart pointer, use a smart
    pointer. std::auto_ptr is a smart pointer you can use, tho I must
    admit I personally don't care for it. (Actually, I don't like smart
    pointers at all, but that's a topic for another show...)

    Repeating another idea many others have suggested, you can also use a
    vector<char>, with which you can accomplish anything a string can do,
    plus much more. Since memory allocated by vector is guaranteed by the
    standard to be contigious, you can use vector::begin() as a char
    const*. If you vector::reserve(), you can also use vector::begin()
    like a writable char* buffer.

    >wish to derive a new class from std::string just for this, and I really just


    There are tools available. Don't reinvent the wheel.

    </dib>

    John Dibling
    email: dib@substitute_my_full_last_name_here.com
    Witty banter omitted for your protection
    </dib>

    John Dibling
    email: dib@substitute_my_full_last_name_here.com
    Witty banter omitted for your protection
     
    John Dibling, Jul 19, 2003
    #19
  20. John Dibling wrote:
    > ...
    > Repeating another idea many others have suggested, you can also use a
    > vector<char>, with which you can accomplish anything a string can do,
    > plus much more. Since memory allocated by vector is guaranteed by the
    > standard to be contigious, you can use vector::begin() as a char
    > const*. If you vector::reserve(), you can also use vector::begin()
    > like a writable char* buffer.
    > ...


    You can use '&*v.begin()' or '&v.front()' or '&v[0]' (where 'v' is
    'std::vector<char>') as char buffer. But not just 'v.begin()'. In some
    implementations 'v.begin()' may return a pointer, but it is not true in
    general case.

    --
    Best regards,
    Andrey Tarasevich
    Brainbench C and C++ Programming MVP
     
    Andrey Tarasevich, Jul 19, 2003
    #20
    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. Peter Jansson
    Replies:
    5
    Views:
    6,354
    Ivan Vecerina
    Mar 17, 2005
  2. lovecreatesbeauty
    Replies:
    1
    Views:
    1,098
    Ian Collins
    May 9, 2006
  3. Jim Langston

    std::string = char* + std::string

    Jim Langston, Jun 30, 2005, in forum: C++
    Replies:
    9
    Views:
    381
    Jim Langston
    Jul 2, 2005
  4. Jeffrey Walton
    Replies:
    10
    Views:
    956
    Mathias Gaunard
    Nov 26, 2006
  5. Replies:
    3
    Views:
    8,830
Loading...

Share This Page