tags:

views:

280

answers:

3

why does this code crash? is using strcat illegal on character pointers?

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

int main()
{
   char *s1 = "Hello, ";
   char *s2 = "world!";
   char *s3 = strcat(s1, s2);
   printf("%s",s3);
   return 0;
}

please give a proper way with referring to both array and pointers.

+10  A: 

The problem is that s1 points to a string literal and you are trying to modify it by appending s2 to it. You are not allowed to modify string literals. You need to create a character array and copy both strings into it, like so:

char *s1 = "Hello, ";
char *s2 = "world!";

char s3[100] = ""; /* note that it must be large enough! */
strcat(s3, s1);
strcat(s3, s2);
printf("%s", s3);

"Large enough" means at least strlen(s1) + strlen(s2) + 1. The + 1 is to account for the null terminator.

That having been said, you should seriously consider using strncat (or the arguably better but nonstandard strlcat, if it is available), which are bounds-checked, and thus are far superior to strcat.

James McNellis
Variable length arrays (c99) or anything less than 100! :P
Mustapha Isyaku-Rabiu
The reason that `strcat` returns its first argument is a convenience for situations just like this one - it means you can do the concatenation in one line: `strcat(strcat(s3, s1), s2);`
caf
I'd actually prefer snprintf to strncat in almost every case like this. It's a minor performance hit, but more likely to be used correctly since strncat's correct usage is inconsistent with the rest of the library. (The 'n' means something different than people seem to think.)
Dan Olson
@rogue: I picked something obviously large enough, then explained what "large enough" really means. You are right that in this case, 100 chars are not required. @caf: That's good to know; I wasn't sure off the top of my head what `strcat` returned (that's what I get for having lived in C++land for too long ;-)). @Dan: Agreed that `strncat` is confusing and difficult (hence the mention of `strlcat`). Actually, `snprintf` might be faster for long strings or a large number of strings since it wouldn't have to walk the destination string to find the terminator for each string being concatenated.
James McNellis
+2  A: 

The correct way in this case would be to allocate enough space in the destination string(s1) to store 6 extra characters(s2) as well as the null terminator for the string.

char s1[14] = "Hello, ";
char *s2 = "world!";
char *s3 = strcat(s1, s2);
printf("%s",s3);
Brandon
A: 

Here is a quote from the strcat() manual : "The strcat() function appends the src string to the dest string, overwriting the null byte ('\0') at the end of dest, and then adds a terminating null byte. The strings may not overlap, and the dest string must have enough space for the result."

The problem here is that s1 and s2 point to static strings which are "read only", so if you try to do a strcat operation, with such a string in the dest parameters, you will get an error.

The best way to create your hello world string here is to malloc it so it will be able to contain both s1 and s2. Also, don't forget to add a '\n' at the end of your printf format string otherwise you might be surprised.

Here is the code I would write if I were you :


int main()
{
  char* s1 = "Hello ";
  char* s2 = "World !";
  char *s3 = malloc((strlen(s1) + strlen(s2) + 1) * sizeof(char));
/* +1 is for the null terminating character
and sizeof(*s3) is the actual size of a char. */

  if (s3)
  {
    strcat(s3, s1);
    strcat(s3, s2);
    printf("%s\n", s3);
    free(s3); // always free what you alloc when you don't need it anymore.
  }
  return 0;
}
Opera