-1

I have a string and I want to change a character on it:

char* myStr = const_cast<char*>("mystr");
myStr[1] = 'a'; //throws an exception

char myStr2[6] = "myStr";
myStr2[1] = 'a';

Why doesn't the last line throw an exception, but myStr[1] = 'a' does?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
John_Cena
  • 45
  • 5
  • Why do you think that doing `myStr[1] = 'a';` is a valid operation? – Evg Apr 15 '23 at 14:55
  • `char myStr2[6] = "myStr";` actually creates a modifiable char array initialized with the content of `"myStr"`. The alternative using `const_cast` is simply undefined behaviour. Probably it doesn't throw an exception, but simply crashes the program; it's undefined behaviour... – fabian Apr 15 '23 at 15:00
  • The code doesn't "throw an exception" in the C++ sense. Your OS reports that something went astray, and often that kind of report uses the word "exception". – Pete Becker Apr 15 '23 at 17:11

1 Answers1

1

There is a reason that "mystr" decays to a pointer of type const char* instead of char*. You are not allowed to modify a string literal. The type is ensuring that you won't be able to try it and the the compiler will tell you if you try, but you chose to tell the compiler that you don't care about the warning by casting const away. You shouldn't expect that to be allowed. const_cast is always dangerous and should only be used if you are 100% sure that the object that the pointer references isn't actually a const object. It is very rarely necessary.

By the way, modifying a string literal will not cause a C++ exception, it will cause undefined behavior.

myStr2[1] = 'a'; is modifying elements of the array named myStr2, not of the string literal. The array is not declared with const, so modifying it is allowed.

If you wrote

const char myStr2[6] = "myStr";

char* myStr = const_cast<char*>(myStr2);
myStr[1] = 'a';

you would have the exact same problem as with the string literal. String literals are also const char arrays.

user17732522
  • 53,019
  • 2
  • 56
  • 105
  • okey, but why is it a const? i can't modify it, but why can't i modify it? why doesn't c++ allow that? why is the behavior undefined? – John_Cena Apr 15 '23 at 15:22
  • @John_Cena To allow the compiler to put the string literals into read-only memory (which the OS may share between multiple processes running the program to save on physical memory) and to reuse the same memory for string literals that have the same value or overlapping values. Basically, to make programs use less memory. This is a decision that C already made a long time ago when it generally was more important to be conservative in memory usage and as you showed, if one really needs to modify the value, storing it in a separate array is still possible. – user17732522 Apr 15 '23 at 16:55
  • 1
    @John_Cena the real question is - why do you want to modify a *read-only string literal* in the first place? – Remy Lebeau Apr 16 '23 at 05:41