STL string and assignment operator. Plz Help.

Discussion in 'C++' started by developer28, Oct 1, 2007.

  1. developer28

    developer28 Guest

    Hi,

    I would like to know the following.

    suppose i write.

    string str1 = "TestString";

    string str2;

    str2 = str1

    Now can someone tell me how this assignment operator works internally.

    actually i do something like

    const char * temp = str1.c_str();

    that converts it to a c type string.

    and then when i modify the contents of temp, it also affects str2.

    Now this makes me doubtful about the fact that internally both the
    objects are using the same pointer.

    Please forgive me if my query is too trivial.

    Thanks for any help.

    Regards,
    Aman.
    developer28, Oct 1, 2007
    #1
    1. Advertising

  2. developer28

    Markus Moll Guest

    Hi

    developer28 wrote:

    > actually i do something like
    >
    > const char * temp = str1.c_str();
    >
    > that converts it to a c type string.
    >
    > and then when i modify the contents of temp, it also affects str2.


    You are not allowed to change the contents through a pointer obtained from
    c_str(): "const charT* c_str() const; [...] Requires: The program shall not
    alter any of the values stored in the array. [...]" (There is a reason why
    c_str() returns a pointer to _const_ char)

    Probably your implementation uses copy-on-write and you screw things up;
    technically you have undefined behavior anyway.

    Markus
    Markus Moll, Oct 1, 2007
    #2
    1. Advertising

  3. On 2007-10-01 13:40, developer28 wrote:
    > Hi,
    >
    > I would like to know the following.
    >
    > suppose i write.
    >
    > string str1 = "TestString";
    >
    > string str2;
    >
    > str2 = str1
    >
    > Now can someone tell me how this assignment operator works internally.


    No, since I do not know how std::string (on your implementation) works.
    But I can make an educated guess.

    > actually i do something like
    >
    > const char * temp = str1.c_str();
    >
    > that converts it to a c type string.
    >
    > and then when i modify the contents of temp, it also affects str2.
    >
    > Now this makes me doubtful about the fact that internally both the
    > objects are using the same pointer.


    They are not using the same pointer, each string uses separate data. A
    simplified string class might look something like this:

    class String
    {
    int size;
    char* data;
    public:
    String& operator=(const String& s)
    {
    delete data;
    data = new char[s.size];
    strcpy(data, s.data);
    size = s.size;
    }
    };

    In other words the assignment operator creates a copy of the string.

    --
    Erik Wikström
    =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=, Oct 1, 2007
    #3
  4. developer28

    Barry Guest

    developer28 wrote:
    > Hi,
    >
    > I would like to know the following.
    >
    > suppose i write.
    >
    > string str1 = "TestString";
    >
    > string str2;
    >
    > str2 = str1
    >
    > Now can someone tell me how this assignment operator works internally.
    >
    > actually i do something like
    >
    > const char * temp = str1.c_str();
    >
    > that converts it to a c type string.
    >
    > and then when i modify the contents of temp, it also affects str2.
    >
    > Now this makes me doubtful about the fact that internally both the
    > objects are using the same pointer.
    >



    [STD --
    21.3.1 basic_stringconstructors

    basic_string<charT,traits,Allocator>&
    operator=(const basic_string<charT,traits,Allocator>& str);

    16 Effects: If *this and str are not the same object, modifies *this as
    effects:

    data() points at the first element of an
    allocated copy of the array whose
    first element is pointed at by
    str.data()

    size() str.size()

    capacity() a value at least as large as size()

    If *this and str are the same object, the member has no effect.
    --End-STD]


    So std::string (basic_string<char>) does not share data with different
    instances.

    So the case you described here is not likely to happen if the
    implementation is standard-conformed.
    Barry, Oct 1, 2007
    #4
  5. On Oct 1, 9:40 pm, developer28 <> wrote:
    > Hi,
    >
    > I would like to know the following.
    >
    > suppose i write.
    >
    > string str1 = "TestString";
    >
    > string str2;
    >
    > str2 = str1
    >
    > Now can someone tell me how this assignment operator works internally.


    Sorry, I can't help you with that.

    > actually i do something like
    >
    > const char * temp = str1.c_str();
    >
    > that converts it to a c type string.


    Modifying a const char* is undefined behaviour, and that
    means that any results you see are possible, albeit right
    or wrong.

    --
    Chris Val
    Chris ( Val ), Oct 1, 2007
    #5
  6. developer28

    Andre Kostur Guest

    =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?= <> wrote in
    news:1T5Mi.10145$:

    > On 2007-10-01 13:40, developer28 wrote:
    >> Hi,
    >>
    >> I would like to know the following.
    >>
    >> suppose i write.
    >>
    >> string str1 = "TestString";
    >>
    >> string str2;
    >>
    >> str2 = str1
    >>
    >> Now can someone tell me how this assignment operator works

    internally.
    >
    > No, since I do not know how std::string (on your implementation)

    works.
    > But I can make an educated guess.
    >
    >> actually i do something like
    >>
    >> const char * temp = str1.c_str();
    >>
    >> that converts it to a c type string.
    >>
    >> and then when i modify the contents of temp, it also affects str2.


    How? It's a pointer to const char. You can't modify it without casting
    away the constness, and at that point you've entered the realm of
    Undefined Behaviour.
    Andre Kostur, Oct 1, 2007
    #6
  7. developer28

    James Kanze Guest

    On Oct 1, 1:40 pm, developer28 <> wrote:
    > I would like to know the following.


    > suppose i write.


    > string str1 = "TestString";


    > string str2;


    > str2 = str1


    > Now can someone tell me how this assignment operator works internally.


    No. It varies from one implementation to the next.

    > actually i do something like


    > const char * temp = str1.c_str();


    Which is something completely different.

    > that converts it to a c type string.


    > and then when i modify the contents of temp, it also affects str2.


    I doubt it. You mean that if later, you do something like:

    temp = NULL ;

    , the contents of str2 (or str1) change? I've never seen
    anything like that, and I don't see how it could be.

    Technically, you cannot modify anything through temp, since it
    points to const. The next version of the standard will have a
    non-const data() function, however, which is expressedly
    designed to allow modification of the string, e.g. by legacy C
    functions which take char* as pointers to a buffer. In
    practice, you can reliably use this today as well, by casting
    away the const on the pointer returned by data(), or by using
    &str[0]. It is, however, very dangerous; any modifications
    beyond str.size() will result in immediate undefined behavior.
    It should only be used when interfacing with legacy code.

    And of course, what happens in str.data() has nothing to do with
    assignment.

    > Now this makes me doubtful about the fact that internally both
    > the objects are using the same pointer.


    The specifications of std::basic_string are fairly complicated,
    intentionally, in order to allow different implementations. The
    user visible semantics, however, are fairly clear, and that's
    all you need to worry about.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Oct 2, 2007
    #7
  8. developer28

    Jim Langston Guest

    "developer28" <> wrote in message
    news:...
    > Hi,
    >
    > I would like to know the following.
    >
    > suppose i write.
    >
    > string str1 = "TestString";
    >
    > string str2;
    >
    > str2 = str1
    >
    > Now can someone tell me how this assignment operator works internally.


    Internally most likely the bytes that represent the string in str1 are
    copied into str2 byte for byte.

    > actually i do something like
    >
    > const char * temp = str1.c_str();


    Here you are not using std::strings copy constructor, you are using a const
    char* copy constructor. The only thing that is copied is the value of the
    pointer that c_str() returns.

    > that converts it to a c type string.


    No, that returns a pointer to a c-style string which is still internal to
    str1

    > and then when i modify the contents of temp, it also affects str2.


    And this is not allowed, This will provoke undefined behavior. First off,
    it's a const char*, constant, you are not allowed to change the contents.
    Second, it is a temporary pointer, as soon as str1 changes for whatever
    reason that pointer can become invalidated. Now, being undefined behavior
    it can pretty much do anything, including change the original string. Or
    change str2. Or str99283. It is undefined behavior. Don't do it.

    > Now this makes me doubtful about the fact that internally both the
    > objects are using the same pointer.


    Both of which objects? str1 and str2? They should be using their own
    pointers to their own sets of data.

    > Please forgive me if my query is too trivial.
    >
    Jim Langston, Oct 2, 2007
    #8
  9. developer28 wrote:
    > string str1 = "TestString";
    >
    > string str2;
    >
    > str2 = str1
    >
    > Now can someone tell me how this assignment operator works internally.


    It depends on the compiler.

    Some compilers implement std::string copying by using the
    copy-on-write technique. This means that only the pointer is copied and
    a reference count incremented. (The deep copy is made only if you try to
    modify one of the strings.)

    Other compilers do a deep copy.

    The standard doesn't enforce any specific method to be used.

    > actually i do something like
    >
    > const char * temp = str1.c_str();
    >
    > that converts it to a c type string.
    >
    > and then when i modify the contents of temp, it also affects str2.


    As people have told you, you shouldn't do that. You are modifying
    the data behind a const pointer, which is asking for trouble.

    Anyways, this would indicate that the compiler you are using is using
    copy-on-write for std::string (and you are circumventing it with your
    modifying-const-data hack).
    Juha Nieminen, Oct 2, 2007
    #9
    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. Chris
    Replies:
    34
    Views:
    1,472
  2. Replies:
    1
    Views:
    354
  3. Replies:
    2
    Views:
    311
    Nick Keighley
    Nov 24, 2006
  4. Replies:
    1
    Views:
    321
  5. nocturnal
    Replies:
    1
    Views:
    498
    nocturnal
    Jul 10, 2009
Loading...

Share This Page