2

Possible Duplicate:
What is the difference between char s[] and char *s in C?

int main()
{
    char *t1 = "Hi hello";
    char t2[] = " strcat";

    printf("%s", strcat(t1, t2));
}

When I run this program it gives me segmentation fault

int main()
{
    char t1[] = "Hi hello";
    char *t2 = " strcat";

    printf("%s", strcat(t1, t2));
}

Whereas when I run the next program it runs properly and shows up the concatenated string. Why is that so ?

Thanks in advance :)

SUMMARY OF THIS QUESTION [SOLVED]

This question is very much closed. Just wanted to add summary. The points which I understood are: For variables declared in this manner

char *t1 = "hi hello";  

Just make sure to add type qualifier const. Since by default it is read-only memory. At any cost we cannot modify the data. For example

t1[0] = "L"; 

is disallowed. Variables declared in this manner are not under our control and will remain forever during the life time of program. We cannot even free that memory.

char t1[10] = "hi hello";

This way we have a better control of the memory. We are permitted to modify the array. Whenever the scope is gone, the allocated memory gets deallocated.

char t1[] = "hi hello"; char t2[8] = "hi hello";

The two declarations t1 and t2 are very much same with 8 character locations allocated sequentially.

Hope I made sense. If not please edit. :)

Community
  • 1
  • 1
Chaitanya
  • 3,399
  • 6
  • 29
  • 47
  • 2
    Both are undefined behaviour. – chris Oct 28 '12 at 18:43
  • 1
    Hopefully your compiler is giving you a waring about both programs along the lines of `warning: conversion from string literal to 'char *' is deprecated` because you shouldn't be saying `char *s = "...";`. Instead you should say `const char *s = "...";` – bames53 Oct 28 '12 at 18:49
  • yes! I agree. But why is that so ? Is it like compiler says so ? :) – Chaitanya Oct 28 '12 at 18:59

4 Answers4

5

t1 is a pointer to a read-only sequence of characters. strcat wants to write into the array pointed to by the first argument, and this is undefined behaviour.

(The second version is also undefined behaviour because you are overrunning the array t1.)

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • How does the second overrun? I thought the `[]` in `char[]` means that the memory will be extended for the array when new elements are inserted? – David G Oct 28 '12 at 18:50
  • Being able to store `"quote delimited"` characters in non-`const char`'s is a legacy issue in C++. Writing to these characters has always been a no-go. In the second version, you initialize a non-`const` array with the `"Hi hello\0"` data, while in the first you create a pointer (that should be `const`) to a data segment protected `"Hi hello\0"`. As every instance of `"Hi hello\0"` in your program can be stored in the same location in the data segment, writing to any of them is bad, and your run time helpfully protects the memory so you get a seg fault instead of random behavior. – Yakk - Adam Nevraumont Oct 28 '12 at 18:51
  • @David -- no, the [] just means that it will be sized to whatever amount of initial data you provide it. The compiler can see from the RHS of the initialization that it needs 9 `char`s in the array. `char foo[] = "Hi hello"` is identical to `char foo[9] = "Hi hello"`, except in the first case the compiler figures out the number 9 for you. – Yakk - Adam Nevraumont Oct 28 '12 at 18:53
  • @David no, char[] when initialized with a string gets allocated the exact space it needs and u can't extend it at a later point of time – zolo Oct 28 '12 at 18:53
  • What does char x = .. (With no pointer or array) mean? – David G Oct 28 '12 at 19:02
  • @Kerrek why is it termed as read only sequence of characters ? – Chaitanya Oct 28 '12 at 19:07
  • @David `char x` is just a single char. For example `char x = 'a'`. – Joseph Mansfield Oct 28 '12 at 19:14
  • @Chaitanya When you do something like `char* str = "foo"`, the pointer `str` points at a location in read-only memory where the bytes 'f', 'o', 'o', '\0' are stored. The correct definition would be `const char* str = "foo"`. Alternatively, when you do `char str[] = "foo"`, the characters are copied from read-only memory into an array of chars - this is *not* const. – Joseph Mansfield Oct 28 '12 at 19:18
  • @sftrabbit so we dont have control on data allocated that way(char *p ="") We cannot deallocate as well. Am I making sense? and what do we mean by this read only memory ? – Chaitanya Oct 28 '12 at 19:33
  • 1
    @Chaitanya: That's just what it is: a string literal (like `"abc"`) is a global, read-only object, namely an array of characters. When it is used to set the value of a `char *` (or rather, a `char const *`), it decays into the address of its first element, so the pointer points to the first element of a sequence of characters, which are immutable. – Kerrek SB Oct 28 '12 at 19:39
  • @KerrekSB Agreed! Its just because the string literal(like "abc") is by itself immutable because that memory will be allocated by the compiler and so the application cannot access that. Correct ? – Chaitanya Oct 28 '12 at 19:48
  • @Chaitanya: You can access the data read-only. You cannot *write* to the memory. That's just what the language standard says. Compilers often put the data in a read-only part of the process's memory, and the OS will kill you if you attempt to write to it. – Kerrek SB Oct 28 '12 at 19:51
0

Both programs are wrong, however the second one could be improved, you need more space in the target array for next sequence:

char t1[100] = "Hi hello"; // at least 16 is needed for t1 + t2 - 100 is just example
char *t2 = " strcat";

Your previous definition:

char t1[] = "Hi hello";

is equivalent to:

char t1[9] = "Hi hello";

or:

char t1[9] = {'H','i',' ','h','e','l','l','o','\0'};

9 is not enough room for both your strings.

PiotrNycz
  • 23,099
  • 7
  • 66
  • 112
  • but when i run it gives not kind of seg fault(about second version). – Chaitanya Oct 28 '12 at 19:05
  • @Chaitanya You are writing to memory which is not yours - it can sometimes happen that this would not cause any wrong behaviour, especially in simple examples. – PiotrNycz Oct 28 '12 at 19:07
  • @Chaitanya See this http://ideone.com/vYAmes – PiotrNycz Oct 28 '12 at 19:10
  • Agreed! It did crash for me as well. But it will be a problem when we try to perform strcat. r else char t1[] = "hello" is as same as char t1[6] = "hello". :) – Chaitanya Oct 28 '12 at 20:07
0

The target array of a call to strcat has to be modifiable memory and large enough to hold the result.

char *t1 = "Hi Hello";   // non-modifiable memory
char t2[16] = " strcat"; // large enough for result, including terminating '\0'
strcat(t2, t1);          // okay

Assuming I've counted right...

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
0

Actually strcat() function append the source string after the destination string. And the second argument should be the source string. Whenever you are running the first sample you are attempting to add t1 string after t2 string. But the size of the t2 string is fixed because it is simply an array of fixed size ( i.e. size can not be increased)