This two codes have to change the char 2 in the character '4'
int main(int argc, char *argv[]){
char *s = "hello";
*(s+2)='4';
printf( "%s\n",s);
return 0;
}
When I run this I get segmentation fault while when I run this:
int main(int argc, char *argv[]){
char *s = argv[1];
*(s+2)='4';
printf( "%s\n",s);
return 0;
}
I know that there are other methods to do this. What is the difference between the 2 programs?
In your first case, you're facing undefined behaviour by attempting to modify a string literal. A segmentation fault is one of the common side-effects of UB.
In your code,
char *s = "hello";
essentially puts the starting address of the string literal "hello" into s. Now, is you want to modify the content of *s (or *(s+n), provided n does not go out of bounds), it will actually try to modify that string literal. As usually, the string literals are stored in the read-only memory, they are usually not allowed to be modified. Quoting from C11, chapter §6.4.5, String literals, (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.
However, in your second case, you're doing
char *s = argv[1];
which is putting the value of argv[1] into s. Now, s points to the string contanied by argv[1]. Here, the contents of argv[1] (or, argv[n], to be general) is not read-only, it can be modified. So, using *s (or *(s+n), provided n does not go out of bounds), you can modify the contents.
This case is defined behaviour, because as per §5.1.2.2.2, Program startup
The parameters
argcandargvand the strings pointed to by theargvarray shall be modifiable by the program, and retain their last-stored values between program startup and program termination.
So, the second case is a special case while using argv[n], which is by the C standard rules, modifiable.
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