My course taught me that char*s are static/read only so I thought that would mean you can't edit them after you have defined them. But when I run:
char* fruit = "banana";
printf("fruit is %s\n", fruit);
fruit = "apple";
printf("fruit is %s\n", fruit);
Then it compiles fine and gives me:
fruit is banana
fruit is apple
Why? Have I misunderstood what it means to be read-only? Sorry if this is obvious but I'm new to coding and I can't find the answer online.
You delete (or delete[]) it when you longer need it and when it points to a char object that you created with new or new[]. You shouls delete/free only if it created with new/malloc, not if it is created on the stack.
The string literal is stored in the read-only part of memory by most of the compilers. The C and C++ standards say that string literals have static storage duration, any attempt at modifying them gives undefined behavior. s is just a pointer and like any other pointer stores address of string literal.
You need to copy the string into another, not read-only memory buffer and modify it there. Use strncpy() for copying the string, strlen() for detecting string length, malloc() and free() for dynamically allocating a buffer for the new string. Show activity on this post. The malloc needs 1 more byte.
Read-Only Memory (ROM) is the primary memory unit of any computer system along with the Random Access Memory (RAM), but unlike RAM, in ROM, the binary information is stored permanently . Now, this information to be stored is provided by the designer and is then stored inside the ROM .
The presented code snippet does not change the string literals themselves. It only changes the values stored in the pointer fruit
.
You can imagine these lines
char* fruit = "banana";
fruit = "apple";
the following way
char unnamed_static_array_banana[] = { 'b', 'a', 'n', 'a', 'n', 'a', '\0' };
char *fruit = &unnamed_static_array_banana[0];
char unnamed_static_array_apple[] = { 'a', 'p', 'p', 'l', 'e', '\0' };
fruit = &unnamed_static_array_apple[0];
These statements do not change the arrays that correspond to the string literals.
On the other hand if you will try to write
char* fruit = "banana";
printf("fruit is %s\n", fruit);
fruit[0] = 'h';
^^^^^^^^^^^^^^
printf("fruit is %s\n", fruit);
that is if you will try to change a string literal using a pointer that points to it (to the first character of the string literal) then the program will have undefined behavior.
From the C Standard (6.4.5 String literals)
7 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.
In your program, the expression "banana"
denotes a string literal object in the program image, a character array. The value of the expression is of type char *
, or "pointer to character". The pointer points to the first byte of that array, the character 'b'
.
Your char *fruit
variable also has type "pointer to character" and takes its initial value from this expression: it is initialized to a copy of the pointer to the data, not the data itself; it merely points to the b
.
When you assign "apple"
to fruit
, you're just replacing its pointer value with another one, so it now points to a different literal array.
To modify the data itself, you need an expression such as:
char *fruit = "banana";
fruit[0] = 'z'; /* try to turn "banana" into "zanana" */
According to the ISO C standard, the behavior of this is not defined. It could be that the "banana"
array is read-only, but that is not required.
C implementations can make string literals writable, or make it an option.
(If you are able to modify a string literal, that doesn't mean that all is well. Firstly, your program is still not well defined according to ISO C: it is not portable. Secondly, the C compiler is allowed to merge literals which have common content into the same storage. This means that two occurrences of "banana"
in the program could in fact be exactly the same array. Furthermore, the string literal "nana"
occurring somewhere in the program could be the suffix of the array "banana"
occurring elsewhere; in other words, share the same storage. Modifying a literal can have surprising effects; the modification can appear in other literals.)
Also "static" and "read-only" aren't synonymous. Most static storage in C is in fact modifiable. We can create a modifiable static character array which holds a string like this:
/* at file scope, i.e. outside of any function */
char fruit[] = "banana";
Or:
{
/* in a function */
static fruit[] = "banana";
If we leave out the array size, it is automatically sized from the initializing string literal, and includes space for the null terminating byte. In the function, we need static
to put the array into static storage, otherwise we get a local variable.
These arrays can be modified; fruit[0] = 'z'
is well-defined behavior.
Also, in these situations, "banana"
doesn't denote a character array. The array is the variable fruit
; the "banana"
expression is just a piece of syntax which indicates the array's initial value:
char *fruit = "banana"; // "banana" is an object in program image
// initial value is a pointer to that object
char fruit_array[] = "apple"; // "apple" is syntax giving initial value
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