Thread: Modifying a string literal.

  1. #16
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Eman View Post
    The first array however does not have char str[] = "Hello World" should not be modifiable because the compiler will implicitly set the length of the array with the null character, any attempts to do a strcat or '+' should result in a seg fault, should it not...?
    There are things you can do to strings that don't involve making them longer.

  2. #17
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    Quote Originally Posted by kmdv View Post
    Actually std::string will make a copy of the given string, but if it is a different class, which does not do that, it still points to the literal.
    A different class which does not do that? I don't understand..there will be cases where the string class would not copy the string? and why should it point?? it is an object not a pointer to a literal... ?

    For #4 you need c_str() member function (will pass pointer to internal buffer, which you must not modify).
    I will quicky google c_str(), no idea what it does..
    You ended that sentence with a preposition...Bastard!

  3. #18
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    Quote Originally Posted by tabstop View Post
    There are things you can do to strings that don't involve making them longer.
    lol you didn't answer my question.

    well yeah true, the only thing i have done so far is convert binary string to floating pointer formats or
    reverse a string that surely is modifying a string, safe because I am not adding or removing stuff. I am using that same string...

    So I am just wondering "You should not modify a string literal..."
    What does that statement mean?
    You ended that sentence with a preposition...Bastard!

  4. #19
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Eman
    A different class which does not do that? I don't understand..there will be cases where the string class would not copy the string? and why should it point?? it is an object not a pointer to a literal... ?
    What kmdv is saying is that you could write another string class that does not perform such copying. Such a custom string object could contain a pointer that merely pointed to the string literal's first character. I do not recommend that you pursue this avenue of thought until you are far more skilled in understanding the basics of the std::string class and how to use it.

    Quote Originally Posted by Eman
    So I am just wondering "You should not modify a string literal..."
    What does that statement mean?
    It means that you should not attempt to assign to any of the characters in a string literal, including the null terminator.
    Last edited by laserlight; 12-27-2010 at 12:41 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #20
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    Quote Originally Posted by Eman View Post
    The first array however does not have char str[] = "Hello World" should not be modifiable because the compiler will implicitly set the length of the array with the null character, any attempts to do a strcat or '+' should result in a seg fault, should it not...?
    Is the concatenation the only operation you can perform on a string? You can also clear it, upper case, remove spaces, do anything which does not exceed the limit. Unfortunately any illegal write does not need to result in a seg fault.

  6. #21
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    oh right...haha I doubt I could do even do what kmdv is thinking even if I wanted to :P


    i tried this:
    Code:
           string str ="Hello" ; 
            printf("%s", str)
    It compiled, I guess because I am using a C++ compiler so it didn't give any errors.
    But what it printed was utter nonsense..
    I had to use
    str.c_str()...which converts str to a c string? I didn't know printfs receive only pointers to strings....
    Last edited by Eman; 12-27-2010 at 12:47 PM.
    You ended that sentence with a preposition...Bastard!

  7. #22
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    Quote Originally Posted by kmdv View Post
    Is the concatenation the only operation you can perform on a string? You can also clear it, upper case, remove spaces, do anything which does not exceed the limit. Unfortunately any illegal write does not need to result in a seg fault.
    yeah I know we can do that, but all this are modifying string literals..
    and my lecturer
    said "You should not modify string literals"
    but in performing those operations, lower to upper, replace whitespace with a comma and all that.. it is still modifying a literal

    haha i am gobsmacked, if it is illegal why not give a seg fault? lol
    You ended that sentence with a preposition...Bastard!

  8. #23
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Eman
    I had to use
    str.c_str()...which converts str to a c string? I didn't know printfs receive only pointers to strings....
    The %s format specifier expects a corresponding argument that is a pointer to the first character of a null terminated string.

    Quote Originally Posted by Eman
    haha i am gobsmacked, if it is illegal why not give a seg fault? lol
    Because it results in undefined behaviour. One characteristic of undefined behaviour is that the code may appear to work perfectly fine until the time when you really need it to work (e.g., when demonstrating the program to the customer in front of the boss), upon which it inevitably fails, whether by crashing or by producing incorrect results.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #24
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    Ok, maybe this will show why and what is illegal:

    Code:
    char* s1 = "LOL";
    char s2[] = "BOB";
    
    "LOL"[0] = 'X'; // #1
    "BOB"[0] = 'X'; // #2
    
    std::cout << s1 << " " << s2 << endl;
    If your compiler merges duplicate constants it will print XOL BOB. The #1 and #2 operations are illegal and will not result in any seg fault probably, good if it does.

    String underlying s1 is a literal, string underlying s2 is NOT (it's a copy).

    Huh.
    Last edited by kmdv; 12-27-2010 at 12:51 PM.

  10. #25
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    Quote Originally Posted by kmdv View Post
    Ok, maybe this will show why what is illegal:

    Code:
    char* s1 = "LOL";
    char s2[] = "BOB";
    
    "LOL"[0] = 'X'; // #1
    "BOB"[0] = 'X'; // #2
    
    std::cout << s1 << " " << s2 << endl;
    If your compiler merges duplicate constants it will print XOL BOB. The #1 and #2 operations are illegal and will not result in any seg fault probably, good if it does.

    String underlying s1 is a literal, string underlying s2 is NOT (it's a copy).

    Huh.
    it isn't working for me! is it because I am using vis studio 2010? It says "expression must be modifiable lvalue"

    omg
    string underlying s2 is a copy....not a literal. But you are copying a literal into a character array. so s2 should be a string literal
    Last edited by Eman; 12-27-2010 at 12:54 PM.
    You ended that sentence with a preposition...Bastard!

  11. #26
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    Code:
    char* s1 = "LOL";
    char s2[] = "BOB";
    
    const_cast<char*>("LOL")[0] = 'X'; // #1
    const_cast<char*>("BOB")[0] = 'X'; // #2
    
    std::cout << s1 << " " << s2 << endl;
    Maybe this will work

  12. #27
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    Quote Originally Posted by kmdv View Post
    Code:
    char* s1 = "LOL";
    char s2[] = "BOB";
    
    const_cast<char*>("LOL")[0] = 'X'; // #1
    const_cast<char*>("BOB")[0] = 'X'; // #2
    
    std::cout << s1 << " " << s2 << endl;
    Maybe this will work
    yeah that worked and gave me an error.

    Code:
    const_cast<char*>("LOL")[0] = 'X'; // #1
    so you are converting a ("LOL")[0] to be a pointer to the string "LOL" to 'L' and you try to write to it by replacing X with the first element 'L' ?
    did your compiler give you no error? maybe i should use borland.

    string underlying s2 is a copy....not a literal.
    But you are copying a literal into a character array. so s2 should be a string literal

    Because it results in undefined behaviour. One characteristic of undefined behaviour is that the code may appear to work perfectly fine until the time when you really need it to work (e.g., when demonstrating the program to the customer in front of the boss), upon which it inevitably fails, whether by crashing or by producing incorrect results.
    yes that happened to me when I was giving my assignment demo I need to learn to use a debugger!
    Last edited by Eman; 12-27-2010 at 01:01 PM.
    You ended that sentence with a preposition...Bastard!

  13. #28
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    Quote Originally Posted by Eman View Post
    yeah that worked and gave me an error.

    Code:
    const_cast<char*>("LOL")[0] = 'X'; // #1
    so you are converting a ("LOL")[0] to be a pointer to the string "LOL" to 'L' and you try to write to it by replacing X with the first element 'L' ?
    did your compiler give you no error? maybe i should use borland.
    What error? Borland has merging off by default. Try this:

    Code:
    char* s1 = "LOL";
    char s2[] = "BOB";
    
    char* lol = "LOL";
    char* bob = "BOB";
    
    lol[0] = 'X'; // #1
    bob[0] = 'X'; // #2
    
    std::cout << s1 << " " << s2 << endl;
    Quote Originally Posted by Eman View Post
    But you are copying a literal into a character array. so s2 should be a string literal
    It copies its contents, not a pointer or something. You get each character from the literal and put it into a buffer. You only read from literal, any write is performed to the buffer not literal.

  14. #29
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The C++ standard states that attempting to modify a string literal results in undefined behaviour. Attempting to modify a string literal means attempting to assign to any of its characters, including the null character. What else do you not understand?

    Trying to come up with code that demonstrates why this rule exists has some merit, but the problem is that this is implementation dependent. The main point is that the contents of a string literal may be stored in a location that is read-only. kmdv's most recent point is that as an optimisation, repeated instances of the same constant may be reduced to a single instance.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #30
    The Dragon Reborn
    Join Date
    Nov 2009
    Location
    Dublin, Ireland
    Posts
    629
    Quote Originally Posted by Eman View Post
    yeah that worked and gave me an error.

    Code:
    const_cast<char*>("LOL")[0] = 'X'; // #1
    so you are converting a ("LOL")[0] to be a pointer to the string "LOL" to 'L' and you try to write to it by replacing X with the first element 'L' ?
    did your compiler give you no error? maybe i should use borland.


    But you are copying a literal into a character array. so s2 should be a string literal



    yes that happened to me when I was giving my assignment demo I need to learn to use a debugger!
    Quote Originally Posted by kmdv View Post
    What error? Borland has merging off by default. Try this:

    Code:
    char* s1 = "LOL";
    char s2[] = "BOB";
    
    char* lol = "LOL";
    char* bob = "BOB";
    
    lol[0] = 'X'; // #1
    bob[0] = 'X'; // #2
    
    std::cout << s1 << " " << s2 << endl;
    the code compiled perfectly, both of them. But on runtime it crashed.
    "Unhandled exception, Access violation.."
    But I don't think that is the outcome you want, because you want to prove to me that a write to a string literal will not always give me a seg fault..

    if Borland doesnt work should I try Dev C++ then? the last of the compiler :O haha

    It copies its contents, not a pointer or something. You get each character from the literal and put it into a buffer. You only read from literal, any write is performed to the buffer not literal.
    So a pointer to a string is a literal. But an array of characters or a string object is not a literal.
    You ended that sentence with a preposition...Bastard!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. question about string literal
    By pangzhang in forum C Programming
    Replies: 6
    Last Post: 07-31-2010, 07:25 AM
  2. Polymorphism and generic lists
    By Shibby3 in forum C# Programming
    Replies: 9
    Last Post: 07-26-2010, 05:27 AM
  3. Replies: 60
    Last Post: 05-31-2010, 10:57 AM
  4. Classes inheretance problem...
    By NANO in forum C++ Programming
    Replies: 12
    Last Post: 12-09-2002, 03:23 PM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM