-1

This works:

int main()
{      
    char *t = "Hello";
    t = "World";
    printf("%s", t);
}

But this gives segmentation fault:

int main()
{   
    char *t = "Hello";   
    strcpy(t, "World"); // the only difference
    printf("%s", t);
}

Why?

Adam Stelmaszczyk
  • 19,665
  • 4
  • 70
  • 110
user2076561
  • 139
  • 1
  • 2
  • 7
  • 1
    `char *t = "Hello";" is a pointer which points to a `string literal`. You can freely assign it to another `string literal` but cannot `store` some data (string e.g.) in this memory. This was the essence of the answer below which I think someone downvoted - If you are the one - please go and upvote it back. – Manoj Awasthi Aug 22 '13 at 19:12

7 Answers7

4

Strings that you define explicitly - e.g. "Hello" - are typically placed in an area of read-only memory. These strings cannot be changed.

In the first example, you are not changing the "Hello" string into the "World" string. You are re-assigning t so that it points to "World" instead of "Hello". The "Hello" string is still hanging around, untouched, in read-only memory.

Here's the initial state:

t -> "Hello"
     "World"

Here's the second state:

     "Hello"
t -> "World"

In the second example, you are trying to overwrite the "Hello" string. This cannot be done.

You should really change your declaration from char *t to const char *t. I think GCC can be configured to enforce this.

Ant
  • 4,890
  • 1
  • 31
  • 42
3

In the first example the pointer t is made to point to a string constant "Hello", and then immediately afterwards to the string constant "World"; the latter value is then printed.

The code in the second example crashes with segfault, because string constants are not writeable. (strcpy tries to modify the memory that holds the text "Hello"). GCC places string constants into a read-only section, unless compiled with -fwriteable-strings.

The code

char *test = "Hello";

means that the compiler+linker place a string of bytes "Hello\0" in a read-only section, and the test points into the first character thereof. Any attempt to write through this pointer would be harshly punished by the operating system.

On the other hand

char test[] = "Hello";

declares an array of 6 characters, with initial value of ({ 'H', 'e', 'l', 'l', 'o', '\0' }).

Some old programs assumed that string constants are writeable; thus requiring GCC to support compiling those programs with the -fwriteable-strings command line switch.

3

The first changes the value of t to point from the address of "Hello" to the address of "World". The second attempts to overwrite the data "Hello" itself.

Theodoros Chatzigiannakis
  • 28,773
  • 8
  • 68
  • 104
2

In char *t="Hello" t assign "Hello" in read only location. So writing to readonly location make segmentation fault.

There is the difference between assigning and copying.

First example you trying to assign the address of another string to t.

In second example you trying to write into readonly location.

use char t[] = "Hello". Here t can be overwrite

more explanation Here

Community
  • 1
  • 1
sujin
  • 2,813
  • 2
  • 21
  • 33
2

The assignment t = "World" changes only the pointer, while the strcpy changes the memory to which t points. String literals may live in a read-only segment.

Fred
  • 8,582
  • 1
  • 21
  • 27
2

char* t is a pointer. In the first example, you are merely assigning the pointer from one string literal to another: first t pointed to "Hello", then to "World". This is perfectly legal.

However, the string literals themselves are literals--they cannot be changed. Typically they are in a read-only section of memory. In the second example, you are attempting to change what is in the memory allocated to the string literal "Hello" by overwriting it with "World". That is illegal and you will get a segmentation fault.

verbose
  • 7,827
  • 1
  • 25
  • 40
1

"Hello" is a string constant. It's not meant to be written on, by the definition of constant.

In your first example, 't' is a pointer, and it can point(be assigned) either string constant.

jaeheung
  • 1,208
  • 6
  • 7