简体   繁体   English

为什么这个简单的C程序在运行时崩溃?

[英]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. 我尝试了以下简单的C程序,但在运行时崩溃,但未提供任何输出。 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 : 根据C标准,更改字符串文字会导致未定义的行为

"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. 但是让我们说说s1不是字符串文字的讨论-您仍然需要有足够的缓冲区供strcat使用-strcat找到nul终止字符并开始在其中写入要附加的字符串。 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. 因为strcat在他的第一个参数上附加了功能。 Ie the result will be store on s1 not on s3 即结果将存储在s1而不是s3上

You should allocate more memory for s1. 您应该为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. 其他人则关注s1没有足够的空间用于字符串连接。 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: s1定义为具有足够空间的char数组应该可以工作:

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. s1是不可变的字符串,将驻留在read-only存储器中。 If you look at the strcat definition: 如果查看strcat定义:

char *strcat(char *dest, const char *src) here 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. dest这是指向目标数组的指针,该目标数组应包含一个C字符串,并且应足够大以包含串联的结果字符串。

so when you are calling char *s3=strcat(s1,s2); 因此,当您调用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. 这里最有问题的是,您将s1s2声明为char *而不是const char* -在这种情况下始终使用const以这种方式初始化字符串时,这是只读存储器。

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. 如果要在s1中扩展字符串,则不应像以前那样初始化它,而应在堆栈或动态内存中为s1分配内存。

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. 我在这里使用了100,因为我认为这足以满足您的字符串要求。 You should always allocate a number that is at least the length of your string + 1 您应始终分配一个至少为字符串长度+ 1的数字

Found a similar one here on comp.lang.c It also answers in depth. comp.lang.c上找到了一个类似的文件。

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不提供自动管理的字符串类型。 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). C编译器仅为源代码中明确提到的对象分配内存(对于字符串,这包括字符数组和字符串文字)。 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. 程序员必须为运行时操作(例如字符串连接)的结果安排足够的空间,通常是通过声明数组或调用malloc来进行。

strcat() performs no allocation; strcat()不执行分配; 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. 该问题中对strcat的最初调用实际上存在两个问题:s1指向的字符串文字,除了对于任何串联文本而言不够大之外,根本不必写。

look at the definition of strcat() 看一下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. dest-这是指向目标数组的指针,该目标数组应包含一个C字符串,并且应足够大以包含串联的结果字符串。

src -- This is the string to be appended. src-这是要附加的字符串。 This should not overlap the destination. 这不应与目的地重叠。

s1 is not enough to hold the concatenated string, which cause to write beyond the limit. s1 不足以容纳连接的字符串,这导致超出限制的写入。 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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