Reputation: 217
The following code raise segment error
from GCC compiler:
char *str1 = "India";
char *str2 = "BIX";
char *str3;
str3 = strcat(str1, str2);
printf("%s %s\n", str3, str1);
The problem is str3=strcat(str1, str2)
.
So my question is: for GCC Compiler, it forbids two pointers pointing to the same thing?
Upvotes: 0
Views: 256
Reputation: 76395
What you should have written, code-wise, answers your question:
char *str1 = "India";
char *str2 = "BIX";
//should have been
const char *str1 = "India";
const char *str2 = "BIX";
The variables str1
and str2
are being assigned the address in memory where the string CONSTANTS India
and BIX
are located. This memory is read-only. You are trying to concatenate these two strings using strcat
. Ok, look at what it does:
strcat(str1, str2);
/\ take this
|| copy ||
===========
add to end
This requires str1
to point to a block of memory big enough to accomodate both itself and the chars that you're concatenating onto it. In case of string literals, this is never the case.
Also remember how I wrote your code with the const
storage class specifier? Now look at strcat
's prototype:
char * strcat(char * destination, const char *source);
The function expects the first argument to be a regular char *
, not a const. This tells you the function will attempt to change the memory the pointer points to. As others have pointed out, and I mentioned above: the memory your str1
pointer points to is read only, hence the segfault.
What you could write is:
char str1[15] = "India";
const char *str2 = "BIX";
strcat(str1, str2);
That ought to work. Note that strcat
does not check/prevent overflow. The size of the destination memory should be big enough to accomodate strlen(source) + strlen(destination) + 1
. Using strncat
instead would be better, still! It allows you to specify a max number of chars to be concatenated onto the destination string:
size_t free_space = 15;
char str1[free_space] = "India";
const char *str2 = "BIX";
free_space -= strlen(str1) + 1;//add 1 here, to ensure we'll have room for the terminating \0 char
char *str3 = strncat(
str1,
str2,
free_space
);
//now we've concatenated something onto our string, keep track of free space left:
free_space -= strlen(str2);//dangerous, though -> size_t is unsigned, perhaps best do:
size_t src_len = strlen(str2);
char *str3 = strncat(
str1,
str2,
free_space
);
if (src_len >= free_space)
free_space = 0;
else
free_space -= src_len;
Upvotes: 1
Reputation: 50774
You need this:
char str1[100] = "India"; // str1 is an array for maximum 100 chars, initialized with "India"
char *str2 = "BIX"; // str2 is a pointer to the string literal "BIX" (read only)
char *str3 ; // str3 is pointer to char
str3 = strcat(str1, str2); // appends "BIX" to "India" in the str1 buffer and puts str1 in str3
printf("%s %s\n", str3, str1);
Upvotes: 0
Reputation: 9680
Trying to change a string literal invokes undefined behaviour. It's read-only even though it's not const
qualified.
str3 = strcat(str1, str2);
The above statement calls strcat
which has prototype
char *strcat(char *dest, const char *src);
Here dest
is a pointer to a buffer which is large enough for the string pointed to by src
to be appended to it. str1
is a pointer to a string literal. Therefore, strcat
will read the characters of the string str2
and write them beyond the string str1
which is illegal.
You don't need to save the return value of strcat
in a separate char *
variable because it modifies its first argument. So after strcat
returns, string pointed to by src
is appended to the one pointed to by dest
. You should change your code to
#define MAX_SIZE 40
char str1[MAX_SIZE] = "India";
const char *str2 = "BIX";
// str1 must be large enough for
// str2 to be appended to it
strcat(str1, str2);
printf("%s %s\n", str2, str1);
Upvotes: 1
Reputation: 10516
strcat
char * strcat ( char * destination, const char * source );
Concatenate strings Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.
destination Pointer to the destination array, which should contain a C string, and be large enough to contain the concatenated resulting string.
But your destination is not pointer to an array(that is large enough to contain the concatenated resulting string) it is a pointer to sting literal, reason for segmentation fault is you are going to write in read only memory locations
Upvotes: 1
Reputation: 15121
Usually, string literals will be put in read-only memory region, your call to strcat()
will try to write to this read-only memory region, therefore segment fault.
Upvotes: 1