I know that const char * is a pointer to a const char, while char *const is a constant pointer to a char.
I am testing this in the following code:
const char *s = "hello"; // Not permitted to modify the string "hello"
char *const t = "world"; // Not permitted to modify the pointer t
s = "hello2"; // Valid
// t = "world2"; // Invalid, gives compilation error
// *(s + 1) = 'a'; // Invalid, gives compilation error
*(t + 1) = 'a'; // Why does this not work?
The last line does not give any error, but causes the program to terminate unexpectedly. Why is modifying the string pointed to by t not allowed?
t is pointing to a string literal it is undefined behavior to modify a string literal. The C++ draft standard section 2.14.5 String literals paragraph 12 says(emphasis mine):
Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementation defined. The effect of attempting to modify a string literal is undefined.
The relevant section from the C99 draft standard is 6.4.5 String literals paragraph 6 which says(emphasis mine):
It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.
On a typical modern Unix platform you will find string literals in the read-only segment which would result in a access violation if we attempt to modify it. We can use objdump to inspect the read-only section as follows:
objdump -s -j .rodata
we can see in the following live example that the string literal will indeed be found in the read-only section. Note that I had to add a printf otherwise the compiler would optimize out the string literal. Sample `objdump output:
Contents of section .rodata:
400668 01000200 776f726c 64002573 0a00 ....world.%s..
An alternative approach would be to have t point to an array with a copy of a string literal like so:
char r[] = "world";
char *const t = r ;
Although string literals in C officially have a type of char[] (array of char, not const), the C standard specifically states that they must be treated as non-modifiable. Compilers tend to put string literals in a read-only segment, so attempting to modify them results in an access violation.
String literals are described in section 6.4.5 of the C11 standard (ISO/IEC 9899:2011).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With