In days of Turbo C/C++ you could easily modify strings like in
char * str = "Hello";
str[1] = '1'; //it will make it H1llo;
Now they are stored in .bss
and you are not allowed to modify them directly. Why? Doesn't this make modifying a string difficult?
Is there any quick fix (but without side-effects) for it? I can strdup()
like functions, but directly modifying strings was real fun.
As you observe, you're not allowed by the Standard to modify the string literals content, and modern compiler's/OSs arrange memory permissions accordingly.
The reason is that the compiler may see a literal used in many places in the code, for example:
in x.cpp: std::cerr << "Error" << separator << msg << '\n';
in y.cpp: if (x == "Error") ...
in z.cpp: q = "StackOverflowError";
It's very desirable to avoid having all those string literals appear separately in the executable image and loaded process memory; instead, the compiler may arrange a single memory region containing "StackOverFlowError\0" and use pointers to the relevant start character (whether the 'S' or 'E') at the points of use.
If you were allowed to modify the value - perhaps deciding that you wanted x.cpp to display "Alert" instead of "Error", it could unintentionally break the code from y.cpp and z.cpp too.
Is there a quick fix?
Well, if depends what you think's broken. If you mean a way to modify the string literals, then no... that's undefined behaviour for the reasons explained above, and the memory protection mechanisms will vary with the OS etc.. If you mean to be able to modify textual data in a similar way, then yes: char* s = "abc";
puts s
on the stack, but it points to that .bss data as you've observed. If you instead write:
char s[] = "abc";
Then s
is still on the stack but is now an array with space for 4 character, the string literal is still in the .bss, but whenever that line runs it copies from the latter to the former, after which you're able to modify the stack-based copy ala s[1] = 'x';
.
Of course, putting your data into a std::string
is normally a better approach.