简体   繁体   中英

Why does this simple C program crash at runtime?

I tried the following simple C program but it crashes at runtime without giving any output. What is wrong here? How can I solve this problem?

#include <stdio.h>
#include <string.h>
int main(void)
{
    char *s1="segmentation";
    char *s2="fault";
    char *s3=strcat(s1,s2);
    printf("concatanated string is %s",s3);
}

So this is the agregated answer for this question:

you should not try to alter string literal in any way. according to the C standard , altering string literals causes undefined behaviour :

"It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined."

but let's say for the discussion that s1 is not string literal - you still need have enough buffer for strcat to work on - strcat finds the nul termination character and start writing on it the string you're appending. if your buffer is not big enough - you will try to write outside the bounderies of your array - causing again undefined behaviour.

Because strcat append functions on his first argument. Ie the result will be store on s1 not on s3

You should allocate more memory for s1. Ie :

 char* s1 = malloc(sizeof(char) * (13 + 6)); //length of your 2 strings
strcpy(s1, "segmentation");
char *s2="fault";
strcat(s1,s2);
printf("concatanated string is %s",s1);

Others are focusing on there is not enough space in s1 for string concatenation. However, the bigger problem here is you are trying to modify a string literal , which is undefined behavior. Defining s1 as a char array that has enough space should work:

char s1[20] = "segmentation";
char *s2 = "fault";
strcat(s1,s2);
printf("concatanated string is %s",s1);

char *s1="segmentation";

s1 is an immutable string, which will be reside in read-only memory. If you look at the strcat definition:

char *strcat(char *dest, const char *src) here

dest -- This is pointer to the destination array, which should contain a C string, and should be large enough to contain the concatenated resulting string.

so when you are calling char *s3=strcat(s1,s2); you are trying to modify the immutable string which result in segmentation fault.

The most problematic thing here is that you declared s1 and s2 as char * and not as const char* - always use const in such case - this is read-only memory when you initialize a string this way.

If you want to extend the string in s1, you should not initialize it as you did, but you should allocate the memory for s1 on the stack or in the dynamic memory.

Example for allocating on the stack:

char s1[100] = "segmentation";

Example for allocating in the dynamic memory:

char *s1 = malloc(100 * sizeof(char));
strcpy(s1, "segmentation");

I used here 100 as I assume that this is enough for your string. You should always allocate a number that is at least the length of your string + 1

Found a similar one here on comp.lang.c It also answers in depth.

the main problem here is that space for the concatenated result is not properly allocated. C does not provide an automatically-managed string type. C compilers allocate memory only for objects explicitly mentioned in the source code (in the case of strings, this includes character arrays and string literals). The programmer must arrange for sufficient space for the results of run-time operations such as string concatenation, typically by declaring arrays, or by calling malloc.

strcat() performs no allocation; the second string is appended to the first one, in place. The first (destination) string must be writable and have enough room for the concatenated result. Therefore, one fix would be to declare the first string as an array:

The original call to strcat in the question actually has two problems: the string literal pointed to by s1, besides not being big enough for any concatenated text, is not necessarily writable at all.

look at the definition of strcat()

char *strcat(char *dest, const char *src)

dest -- This is pointer to the destination array, which should contain a C string, and should be large enough to contain the concatenated resulting string.

src -- This is the string to be appended. This should not overlap the destination.

s1 is not enough to hold the concatenated string, which cause to write beyond the limit. It causes the run-time failure.

try this,

char *s1="segmentation";
char *s2="fault";
char* s3 = malloc(sizeof(s1) + sizeof(s2));
strcpy(s3, s1);
strcat(s3, s2);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM