我尝试了以下简单的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);
}
答案 0 :(得分:7)
所以这是这个问题的回答:
你不应该尝试以任何方式改变字符串文字。根据C标准,更改字符串文字会导致未定义的行为:
&#34;未指明这些数组是否与它们不同 元素具有适当的值。如果程序试图 修改这样的数组,行为是未定义的。&#34;
但是让我们来讨论s1不是字符串文字 - 你仍然需要有足够的缓冲区让strcat工作 - strcat找到nul终止字符并开始在其上写下你的字符串追加。如果你的缓冲区不够大 - 你会尝试在数组的bounderies之外写 - 导致再次出现未定义的行为。
答案 1 :(得分:3)
因为strcat在他的第一个参数上追加函数。 即结果将存储在s1而不是s3
您应该为s1分配更多内存。 即:
int count = "phahahahoto".split("(?=haha)").length - 1;
//=> 2
答案 2 :(得分:3)
其他人则关注s1
中没有足够的空间来进行字符串连接。但是,这里更大的问题是您正在尝试修改字符串文字,这是未定义的行为。将s1
定义为具有足够空间的char数组应该可以工作:
char s1[20] = "segmentation";
char *s2 = "fault";
strcat(s1,s2);
printf("concatanated string is %s",s1);
答案 3 :(得分:2)
char *s1="segmentation";
s1
是一个不可变的字符串,它将驻留在read-only
内存中。如果你看一下strcat
定义:
char *strcat(char *dest, const char *src)
here
dest
- 这是指向目标数组的指针,该数组应该包含一个C字符串,并且应该足够大以包含连接的结果字符串。
所以当你调用char *s3=strcat(s1,s2);
时,你试图修改导致分段错误的不可变字符串。
答案 4 :(得分:1)
这里最有问题的是您将s1
和s2
声明为char *
而不是const char*
- 在这种情况下始终使用const
- 这以这种方式初始化字符串时,只读内存。
如果你想在s1中扩展字符串,你不应该像你那样初始化它,但你应该在堆栈或动态内存中为s1
分配内存。
在堆栈上分配的示例:
char s1[100] = "segmentation";
在动态内存中分配的示例:
char *s1 = malloc(100 * sizeof(char));
strcpy(s1, "segmentation");
我在这里使用 100 因为我认为这对你的字符串来说已经足够了。您应该始终分配一个至少是字符串长度+ 1
的数字答案 5 :(得分:1)
在comp.lang.c上找到类似的内容。它也深入回答。
这里的主要问题是连接结果的空间不是 适当分配。 C不提供自动管理的字符串 类型。 C编译器仅为对象明确分配内存 在源代码中提到(在字符串的情况下,这包括 字符数组和字符串文字)。程序员必须安排 足够的空间用于运行时操作的结果,例如字符串 连接,通常通过声明数组或调用malloc。
strcat()不执行任何分配;第二个字符串被附加到 第一个,到位。第一个(目标)字符串必须是可写的 并有足够的空间来连接结果。因此,一个修复 将第一个字符串声明为数组:
问题中对strcat的原始调用实际上有两个问题: s1指向的字符串文字,除了不够大 任何连接的文本,根本不一定是可写的。
答案 6 :(得分:0)
查看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);