Are string literals constant or not? [duplicate] - c

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is it possible to modify a string of char in C?
char *s = "anusha";
Is this like a constant pointer? When i tried to change the character in location 3 by writing s[3]='k', it gave me a segmentation fault. So i am assuming it is like pointing to a constant array or s is a constant pointer? Which among the two? Please clarify.

That is correct, you are not allowed to modify string literals.
However, it's legal to do this:
char s[] = "anusha";
s[3] = 'k'
The difference here being that it is stored as a local array that can be modified.

It looks like your compiler treats "anusha" as a pointer to char, but places the string itself into write-protected memory. I remember reading that this is a convenience policy in order to comply with existing code.
As Joe pointed out, this is detailed in Is it possible to modify a string of char in C?.

Related

Why can't I change a string by index when it is declared by pointer notation? [duplicate]

This question already has an answer here:
Why can I not modify a string literal in c?
(1 answer)
Closed 4 months ago.
for example:
char stringer[]="hello";
stringer[2]='A';
The above works to change 'l' to 'A'. But if I do the following:
char *stringer="hello";
stringer[2]='A';
This doesn't work, is there a reason for this?
As answered by Some programmer dude in comments:
Literal strings are really non-modifiable arrays of characters. With char *stringer="hello"; you make stringer point to the first character of such an array. Attempting to modify its contents leads to undefined behavior.
That's why you should always use const char * when pointing to literal strings.
Strings can be modified when using pointer, if the pointer is pointing to something you're allowed to modify. For example
char stringer[] = "hello";
char *pointer = stringer;
pointer[2] = 'A';

What is the difference between these two definitions? [duplicate]

This question already has answers here:
Memory Allocation char* and char[]
(3 answers)
Closed 6 years ago.
What is the difference between these two definitions?
char *string = "MyString";
char string[] = "MyString";
As much as I know, the first one is a pointer to a string.
The first is a pointer to a string literal, the second is an array initialized with the contents of the string literal (which BTW when optimized points exactly to where string points).
The first one lives in the read only segment of the program's memory and thus cannot be modified.
The second one is an array of 9 elements and you can modify any of the 9 elements including the termnating null byte that is not explicitly set in the code in your question.

Compiler crashes when printing a pointer related code [duplicate]

This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 7 years ago.
Today when learning pointer in C, I have faced a problem. I wrote this code:
#include<stdio.h>
int main()
{
char *p="XAD";
printf("%c\n",(*p));
printf("%c\n",++(*p));
return 0;
}
First printf() shows correct output and it is X. But for second output, compiler crashes. But why? If (*p) gives 'X'(as expected), then ++(*p) should give 'Y'. Shouldn't it?
Here:
char *p="XAD";
You create a pointer p and assign it to the string literal "XAD". String literals are immutable, meaning that it cannot be changed. The ++(*p) dereferences the pointer p and increments it, thus attempting to change the contents of the string literal (Specifically, the first character). Attempting to modify a string literal leads to Undefined Behavior as seen in the C11 standard (emphasis mine):
6.4.5 String literals
[...]
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
Fix the problem by either declaring p as an array or using (*p)+1 instead of ++(*p). Using the former will not modify the contents of the string literal while the latter does.
The pointer p points to a string literal. Modifying a string literal results in undefined behaviour in C.
Change
char *p="XAD";
to
char p[]="XAD";
which will allow you to modify it since p is an array here.
While char *p="abc"; is perfectly valid in C, in general, string literals should be declared with const keyword as you are not allowed to modify it anyway. This will help catch an accidental change. It should have been of type const char[] but it is of type char [] is because of "historical" reasons (C++ corrected it).
Or you simply interested in printing a modified value, you can do:
printf("%c\n", (*p) + 1);
as suggested by #alk, which does what you code attempts to do but without modifying the string itself.

String constants vs char arrays in C [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What is the difference between char s[] and char *s in C?
More of a general question rather than trying to fix something, I've been reading the C programming language book and they take care to make the distinction between
char amessage[] = "blah";
char *pmessage = "blah";
The difference being one is a char array and the other a pointer to a string constant. They say modifying the char array is acceptable but you shouldn't modify string constants as it triggers undefined behavior. My question is: isn't the string constant stored in memory the same way the char array is? Why can I modify it as in
char *p = "this is a string constant";
*(p+2) = 'a';
printf("%s", p);
Ends up printing "thas is a string constant" as you might expect. I can understand how it would make sense as a string constant shouldn't end up being changed at run time, as it might confuse others/yourself working on your code not expecting it's value to change but in purely functional terms what is wrong with it, what is the undefined behavior that might trigger and how mechanically could it backfire when a char array wouldn't? I'm just wondering if I'm missing something about how string constants work in memory and how they are seen by the compiler.
At least on my computer, the following program crashes:
#include <stdio.h>
int main() {
char *p = "this is a string constant";
*(p+2) = 'a';
printf("%s", p);
}
If it appears to be working for you (which it might on certain embedded compilers), you're just getting lucky. Undefined behavior means the program is allowed to do anything. See http://blog.regehr.org/archives/213 .
See also What is the difference between char s[] and char *s?.
In case of char array the content of the string literal "blah" are copied on to the stack as well. So you can modify it without invoking UB because after all its just a copy.
In case of char * you actually try to modify the original string literal and as per the Standard that is UB.
With a string constant, there's not guarantee about where the data will be stored -- the compiler is free to do any tricks it wants, because you're supposed to be forbidden from writing to it. So for example, it's not unheard of for the pointer to actually point to the spot in the loaded executable code itself where the string constant is defined.

Declaration of strings in C [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Is it possible to modify a string of char in C?
What is the difference between char s[] and char *s in C?
There is something I don't understand about strings and pointers in C.
Suppose I have this declaration:
char str[] = "abc";
Then, if I attempt to modify it this way:
str[0] = 'b';
It will work.
But if I declare the string as a pointer to a char
char* str = "abc"
The attempt above will cause an access violation.
What I'm trying to understand is what exactly is the difference.
Thanks in advance
In The later example the compiler puts the string in the read only data section, so u can't modify it. But in earlier example you are declaring array of character which resides in stack hence you can modify content of this array.

Resources