Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify a string with pointer [duplicate]

Tags:

c

string

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?

like image 279
joumvaer92 Avatar asked May 09 '26 10:05

joumvaer92


1 Answers

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 argc and argv and the strings pointed to by the argv array 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.

like image 140
Sourav Ghosh Avatar answered May 11 '26 04:05

Sourav Ghosh