3

为什么会发生以下情况:

char s[2] = "a";
strcpy(s,"b");
printf("%s",s);

--> 执行没有问题

char *s = "a";
strcpy(s,"b");
printf("%s",s);

--> 段错误

第二个变体不应该也分配2个字节的内存s,因此有足够的内存可以复制到"b"那里吗?

4

3 回答 3

12
char *s = "a";

指针s指向字符串字面量"a"。尝试对此进行写入具有未定义的行为,因为在许多系统上,字符串文字存在于程序的只读部分中。

字符串文字是类型char[N]而不是const char[N]使它更清晰是历史的偶然。

于 2012-06-12T09:47:35.240 回答
5

第二个变体不应该也为 s 分配 2 个字节的内存,从而有足够的内存来复制“b”吗?

不,char *s指向包含字符串的静态内存地址"a"(写入该位置会导致您遇到的段错误),而char s[2];它本身提供了字符串所需的空间。

如果要手动为字符串分配空间,可以使用动态分配:

char *s = strdup("a"); /* or malloc(sizeof(char)*2); */
strcpy(s,"b");
printf("%s",s); /* should work fine */

之后不要忘记free()你的字符串。

于 2012-06-12T09:49:21.943 回答
1

总而言之,另一种方式/答案:我认为错误在于您没有创建指针必须指向的变量,因此是段错误。

我遵循的一条规则:声明一个指针变量不会创建变量的类型,它指向。它创建一个指针变量。因此,如果您指向字符串缓冲区,则需要指定字符数组和缓冲区指针并指向字符数组的地址。

于 2012-06-12T12:35:39.197 回答