Modifying string value causes access violation [duplicate] - c

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 2 years ago.
I have the following code:
int main()
{
char *input = "why isn't this possible?";
input[0] = 'W';
return 0;
}
I want to modify the first value of the string, but it appears to cause an access violation on the input[0] = 'W'; line.
Any ideas why this is happening. Oddly I don't recall this error happening on my old machine running Visual Studio, but happens with GCC and Pellas C.

First of all, what your attempting to modify is not a string, it's a string literal.
Yes, you see different behaviour in different cases because this attempt is mentioned to exhibit undefined behaviour in C standard.
Quoting C11, chapter 6.4.5, String literals
[...]If the program attempts to modify such an array, the behavior is undefined.
To achieve the expected output, you can simply use an array, initialized by the string literal and them attempt to modify the array element. Something like:
int main(void)
{
char input[ ] = "why isn't this possible?"; // an array
input[0] = 'W'; // perfectly modifiable
return 0;
}

Any attempt to modify a C string literal has undefined behaviour. A compiler may arrange for string literals to be stored in read-only memory (protected by the OS, not literally ROM unless you're on an embedded system). But the language doesn't require this; it's up to you as a programmer to get it right.
Try this if you want the functionality:
int main()
{
char input[] = "why isn't this possible?";
input[0] = 'W';
return 0;
}
Otherwise to learn more on it, check this answer out:
Char* and char[] and undefined behaviour

Related

Why does scanf("%s") behave strangely with char*? [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 2 years ago.
I was trying to solve this problem
When i create a char * and pass it into scanf:
char* input = "";
scanf("%s", input);
It behaves weirdly.
However, when i change the definition and initalize 1000 chars to \0:
char input[1000] = { '\0' };
It behaves properly. Why is it that way?
I'm guessing you're seeing a segmentation fault. When you declare char* input = "";, you're causing input to be a pointer directed at a string literal. String literals are stored in a read-only section of memory. Therefore, trying to overwrite the data with scanf is an invalid use of memory.
However, when you declare char input[1000];, you've now got an array on the stack, which is a section of memory which can be written to. That's why that code works.
First question is what does this declare?
char* input = "";
That's a single byte in a non-mutable (read-only) area of memory. If you write anything to it, that's undefined behaviour, or something more colloquially described as weird behaviour.
When you re-write it correctly you get a 1000 character buffer and you can read to it without undefined behaviour, provided your input is < 1000 characters.

Segmentation Fault in char pointer [duplicate]

This question already has answers here:
Modify a string with pointer [duplicate]
(4 answers)
Closed 5 years ago.
I am getting segmentation fault when running the below code. What could be the reason for this error? Please help
int main()
{
char *str2 = "Hello";
str2[3] = 'J';
printf("%s\n",str2);
return 0;
}
It is a undefined behaviour because you are trying to modify the content of a string literal. A string literal mainly stored in a read only location. so you do not modify it, otherwise it is invoked undefined behaviour.
C11 §6.4.5 String literals(Paragraph 7):
It is unspecified whether these arrays are distinct provided their
elements have the appropriate values.If the program attempts to
modify a string literal of either form, the behavior is undefined"
You aren't allowed to modify a string constant, and in this case it's causing a runtime error. You can fix it by changing the declaration of str2 to:
char str2[] = "Hello";
This makes it an array, rather than a pointer to a string constant.
You are not allowed to modify the memory pointed to by char* variables initialized with string literals. It is read-only.

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.

not able to modify strings on stack in c [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Why does char* cause undefined behaviour while char[] doesn’t?
The following code
int main() {
char * st = "abc";
*st = 'z';
return 0;
}
is returning a segmentation fault. If the strings on the stack are not modifiable why is it not giving the error at compile time?
The variable on the stack, st, is a pointer. The value assigned is to a string constant (read-only).
char *str = "this is dangerous to modify"; is not a string in the same sense you get; it's called a string-literal and modifying it produces undefined behavior according to the standard.
If you want a string that you can later modify, go like this:
char str[] = "Some String";
then modify it accordingly.

Segmentation Fault ++operator on char * [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why does this Seg Fault?
I receive a segmentation fault when using ++ operator on a char *
#include<stdio.h>
int main()
{
char *s = "hello";
printf("%c ", ++(*s));
return 0;
}
But if I do the following:
#include<stdio.h>
int main()
{
char *s = "hello";
char c = *s;
printf("%c ", ++c);
return 0;
}
Then the code compiles perfectly, what is the problem with the above code?
The first code snippet is attempting to modify a character in a string literal as:
++(*s)
is attempting to increment the first character in s. String literals are (commonly) read-only and an attempt to modify will cause the segmentation fault (the C standard states If the program attempts to modify such an array, the behavior is undefined.).
The second snippet is modifying a char variable, which is not read-only as after:
char c = *s;
c is a copy of the first character in s and c can be safely incremented.
In the first case you modify a constant literal, and in the second you modify a variable.
This code:
printf("%c ", ++(*s));
tries to modify a string literal through a pointer to one of its characters. Modifying string literals is undefined behavior - the quite likely outcome is that string literals are often stored in read-only memory, so it's technically illegal to modify them and that's why it manifests itself as segmentation fault on your system.
char *s = "hello";
This implies that 's' is a const string.
If you need a non-const string, you should allocate it explicitly from heap.
You are trying to change a string literal in the first case which is not allowed. In the second case you create a new char from the first character of the string literal. You modify the copy of that character and that is why the second case works.
Your code does not have write permission for the segment where the string literal is stored.

Resources