[英]Why does this simple C program crash at runtime?
我尝试了以下简单的C程序,但在运行时崩溃,但未提供任何输出。 怎么了 我怎么解决这个问题?
#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);
}
因此,这是此问题的汇总答案:
您不应尝试以任何方式更改字符串文字。 根据C标准,更改字符串文字会导致未定义的行为 :
“尚不清楚这些数组是否有区别,只要它们的元素具有适当的值。如果程序尝试修改此类数组,则行为是不确定的。”
但是让我们说说s1不是字符串文字的讨论-您仍然需要有足够的缓冲区供strcat使用-strcat找到nul终止字符并开始在其中写入要附加的字符串。 如果缓冲区不够大-您将尝试在数组的边界之外写-再次导致未定义的行为。
因为strcat在他的第一个参数上附加了功能。 即结果将存储在s1而不是s3上
您应该为s1分配更多的内存。 即:
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);
其他人则关注s1
没有足够的空间用于字符串连接。 但是,这里更大的问题是您试图修改字符串文字 ,这是未定义的行为。 将s1
定义为具有足够空间的char数组应该可以工作:
char s1[20] = "segmentation";
char *s2 = "fault";
strcat(s1,s2);
printf("concatanated string is %s",s1);
char *s1="segmentation";
s1
是不可变的字符串,将驻留在read-only
存储器中。 如果查看strcat
定义:
char *strcat(char *dest, const char *src)
在这里
dest
这是指向目标数组的指针,该目标数组应包含一个C字符串,并且应足够大以包含串联的结果字符串。
因此,当您调用char *s3=strcat(s1,s2);
您正在尝试修改不可变的字符串,这会导致分段错误。
这里最有问题的是,您将s1
和s2
声明为char *
而不是const char*
-在这种情况下始终使用const
以这种方式初始化字符串时,这是只读存储器。
如果要在s1中扩展字符串,则不应像以前那样初始化它,而应在堆栈或动态内存中为s1
分配内存。
在堆栈上分配的示例:
char s1[100] = "segmentation";
在动态内存中分配的示例:
char *s1 = malloc(100 * sizeof(char));
strcpy(s1, "segmentation");
我在这里使用了100,因为我认为这足以满足您的字符串要求。 您应始终分配一个至少为字符串长度+ 1的数字
在comp.lang.c上找到了一个类似的文件。
此处的主要问题是未正确分配用于级联结果的空间。 C不提供自动管理的字符串类型。 C编译器仅为源代码中明确提到的对象分配内存(对于字符串,这包括字符数组和字符串文字)。 程序员必须为运行时操作(例如字符串连接)的结果安排足够的空间,通常是通过声明数组或调用malloc来进行。
strcat()不执行分配; 第二个字符串就位附加到第一个字符串。 第一个(目标)字符串必须是可写的,并且有足够的空间容纳级联结果。 因此,一种解决方法是将第一个字符串声明为数组:
该问题中对strcat的最初调用实际上存在两个问题:s1指向的字符串文字,除了对于任何串联文本而言不够大之外,根本不必写。
看一下strcat()
的定义
char *strcat(char *dest, const char *src)
dest-这是指向目标数组的指针,该目标数组应包含一个C字符串,并且应足够大以包含串联的结果字符串。
src-这是要附加的字符串。 这不应与目的地重叠。
s1
不足以容纳连接的字符串,这导致超出限制的写入。 它会导致运行时失败。
尝试这个,
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.