2.7k views

Consider the following C program segment.

# include <stdio.h>
int main()
{
char s1[7] = "1234", *p;
p = s1 + 2;
*p = '0';
printf("%s", s1);
}

What will be printed by the program?

1. $12$
2. $120400$
3. $1204$
4. $1034$

edited | 2.7k views
+1
One more key learning here.

If it would have been char *s= "1234", then it will be stored as a string constant in the data segment(read-only). we cannot change the content of string using another pointer. It will give an error.
0

p = s1 + 2;

Type of s1 is char[7] and sizeof *s1 is sizeof (char) = 1. So, s1 + 2 will return address in s1 + 2 *sizeof(char) = address in s1 + 2. So,  $p$ now points to the third element in s1.

*p = '0';

The third element in s1 is made $0$. So, $1234$ becomes $1204$. C choice.

by Veteran (424k points)
edited by
0
what happen if ' a'. Is 12a4 printed? I want how above works
0

Yes .Similar working as above. Execute this code

# include <stdio.h>
int main()
{
char s1[7] = "1234", *p;
p = s1 + 2;
*p = 'a';
printf("%s", s1);
}

0
here why not b??
+5
@priyanka There is no string in C language. So, for using a string we start at any address and scan characters from consecutive locations until a '\0' character which is byte value 0 is encountered. This is how all string functions in C works - including "%s" in printf, strlen, strcpy, strcat etc.
0
okk means the empty location are consider as null chracter or not like array where we initialise them as 0
+11
No. There is no empty location in C/C++. All memory locations by default have garbage (static/global variables are initialized though). So, for string ending character we have to put '\0' or equivalently 0 to that location. But when we use string literals like "1234" compiler adds this '\0' at end and makes it 5 bytes which contain "1", "2", "3", "4", "\0" in consecutive memory locations.
+1
"scan characters from consecutive locations until a '\0' character"

@arjun sir, in that case ans should be (A)12 because it print upto null char...???
+1
@sanyam you are correct. But it was a typo in question. It was '0' and not '\0'; corrected now.
0

I read, that string is a ROM location of computer memory. It's value cannot be changed. And if u change it's value, it will terminated abnormally.

So, why is it not similar to this program too?

@Arjun Sir

0
All Strings Not placed in read only memory... Only constant strings are placed in rom
0

@Shaik Masthan

why this string not a constant string??

0
0

@Gaurav_Singh2

Sorry, still my doubt not cleared

Can u explain , if u got my point.

+1

When we write

1.

char *s ="hello";

Creates two objects:

• read-only array of 6 chars containing the values 'h', 'e', 'l', 'l', 'o', '\0', which has no name and has static storage duration (meaning that it lives for the entire life of the program); and
• a variable of type pointer-to-char, called s, which is initialized with the location of the first character in that unnamed, read-only array.

The "read-only memory"  is the text segment in the program. The same place in memory where the instructions are loaded. When you create a char* initialized to a string, the string data is compiled into the text segment and the program initializes the pointer to point into the text segment and our text segment is of type read-only for obvious reasons like security.

So, when we try to change it, a Segmentation fault occurs.

2.

char s[] = "hello";

Creates one object - a char array of size 6, called s, initialized with the values 'h', 'e', 'l', 'l', 'o', '\0'. Where this array is allocated in memory depends on where the declaration appears. If the declaration is within a function, it is  allocated on the stack; if it's outside a function, it will probably be stored within an "initialized data segment" which we can safely alter at run time.

Now, in this case character array s1 is created inside the stack section of the memory and p is a pointer to a character. In the second line p is storing the address of the third element of the array.

Notice that p is not pointing to the text segment of the program which is read-only and alteration would give segmentation fault, here p is pointing to the stack section so we can safely alter the values that's why when we do *p = '0' ; it is valid.

0

@Gaurav_Singh2

Good .

So, u mean char s1[]="1234" and try to alter 3 as 0, then it will give segmentation fault??

0

@srestha try visualising these 3 codes

Code 1

#include <stdio.h>
int main()
{
char s1[] = "1234";
printf("%s\n", s1);
s1[2] = '0';
printf("%s", s1);
return 0;
}

O/P : 1234
1204

Code 2:

# include <stdio.h>
int main()
{
char *s1 = "1234";
printf("%s", s1);
return 0;
}

O/P :  1234

Code 3:

# include <stdio.h>
int main()
{
char *s1 = "1234";
s1[2] = '0';
printf("%s", s1);
return 0;
}

O/P : Segmentation Fault (SIGSEGV)

0

but , this(https://ideone.com/Nmgmia) is not seg fault, as u written :(

0
Yes, this is not a segmentation fault because global string s1 would be stored in the initialized read-write area of the initialized data segment and p is the pointer which stores the address of the third element of the array as defined by you.

Now, since the pointer p here is pointing to the initialized data segment which is read-write type so doing *p='0' is valid.

But earlier in the above comment point 1, s was pointing to the text section and the text section is read-only type. So, when we will try to do *s='0' then it will cause a segmentation fault.
0

@Gaurav_Singh2

Is that means, if we modify some value, inside a array that initialized a string, is still no error will occur?? But why not?? Is it's value not constant??

0

What I mean see below:

check this similar kind of program

main(){
printf("%s",*("INDIA"+2)='I');
}

will give abnormal termination. Why same thing will not happen here??

0

For the confused people,
*p = '0';    So answer is 1204
If *p = 0;   Here answer will be 12

0 means Ascii 0  which is Null character.

'0'  means Ascii 48 which is character '0'

by Boss (12.2k points)
edited by
+1
If *p = 0, then will there be an error? As integer value is assigned to char variable.
+1
No, a char can hold upto 255.
0
@Ahwan

NULL has nothing to do with strings, it is a macro defined in stddef.h

'\0' has ascii value of 0 which is used at the end of each string
0
Is it fine now?
0
Yes.
0

what is the difference between *p = '0'  &  *p = 0. I can't understand.

0

*p = '\0' will also print  12

this assumption  is wrong because there is nothing like character '\0' in and may lead to error as we assigning 2 char in one location.

Am I right  @Arjun Sir?

+2
No. \0 is a valid character as \ is an escape character and it's ASCII code is 0.
0
Anything which can be stored in 1Byte is called as char. Computer understands this only. Although we are able to see that 0 is integer. But computer checks whether the thing can be stored in 1 byte or not..
Here s1 is an array, So s1 points to base address.

so , p=s1+2 will point to 3rd element of s1.

and *p='0'

value at p (Which is the third element of s1) , so 1234 becomes 1204.
by Active (1.7k points)
+1 vote
by
s1[7]="1234"

p=s1+2

it is pointing to the address of "3" of "1234"

if *p=0 then the value of 3 replaced by 0

so the printf("%s", s1) prints 1204
by (11 points)