0

The following two code snippets compiles without any errors/warnings but while running it crashes. Kindly enlighten me.

Program 1

 int main( )
{
   char *p= "Hello" ;

   *p = 'B' ;
    printf("\n%s",p);

   return 0;
}

Program 2

int main( )
{
   char *p= "Hello" ;
   Char *q="mug"
   *q = *p ;
    printf("\n%s",q);

   return 0;
}

For program 2 i expected output to be 'Hug'.

6 Answers 6

8

When you do:

char *p= "Hello";

You are defining a string literal. String literals are constant data and as you've found out, modifying them results in undefined behavior (often a crash). It should be declared as:

const char *p = "Hello";

So the compiler will throw an error if you try to modify it.

Now if you define it instead as:

char p[] = "Hello";

The memory is then allocated on the stack and you can modify it.

int main(int argc, char *argv[])
{
    char p[] = "Hello" ;

    *p = 'B' ;
    printf("\n%s",p);

    return 0;
}

Outputs Bello

For program 2, note only q needs to be on the stack. p can remain a const pointer to a string literal, since you're only reading from it.

int main( )
{
    const char *p = "Hello" ;
    char q[] = "mug";
    *q = *p ;
    printf("\n%s",q);

    return 0;
}

Outputs Hug

Sign up to request clarification or add additional context in comments.

Comments

0

In both samples you are modifying string literals, which yields undefined behavior.

Comments

0

When you create a static string in the form of char *p = "test" the contents of the pointer cannot be changed. In your case trying to modify the contents of the pointer yields to the error that you are observing.

Comments

0

I changed program 2 to not use string literals. It shows "Hug" as you expected.

#include <string.h>
#include <stdio.h>

int main( )
{
   char p[10];
   char q[10];
   strcpy(p,"Hello");
   strcpy(q,"mug");
   *q = *p ;
   printf("\n%s",q);

   return 0;
}

1 Comment

There are already 4 answers to why the code fails. This answer explains how to do it right.
0

What you should write is:

char p[] = "Hello";

The form above (char p [] = "Hello") tells the compiler, "I've got an array of values coming up, please allocate as much space as is needed for them." It also works with ints, for example:

int i [] = { 1, 2, 5, 100, 50000 };

You'll end up with i being a pointer to an array of 5 values.

1 Comment

Yeah, I realized that shortly after I posted it and removed it. Sorry for the confusion.
0

The strings "Hello" and "mug" are stored in read-only memory and you are trying to write there.

$ gcc -S a.c
$ cat a.s
    .file   "a.c"
    .section        .rodata
.LC0:
    .string "Hello"
.LC1:

Note that the section is "rodata" (read-only data).

2 Comments

Atom does it mean the literal is stored in "Code/text segment". That is why it becomes RO?
The literal is stored in section ".rodata", which contains data (not code), and the flags in the ELF executable are saying that the section is read-only. There are also other sections such as ".text" and ".data". You can use "readelf --sections executable_file" to print all the sections, the "Flg" column specifies the section's access rights.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.