为什么strcpy在char *s时失败但在char s[1024]时不会失败?

3
为什么会发生以下情况:
char s[2] = "a";
strcpy(s,"b");
printf("%s",s);

--> 成功执行

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

--> 段错误

第二个变量定义的时候会为s分配两个字节的内存,为什么不能将"b"复制到那里呢?

3个回答

12
char *s = "a";
指针 s 指向字符串字面值 "a"。尝试对其进行写操作会导致未定义行为,因为在许多系统中,字符串字面值位于程序的只读部分。
历史原因导致字符串字面值的类型是 char[N] 而不是更明确的 const char[N]

2
字符串字面量的类型为char[N],其中N是包括空字符终止符在内的字面量长度。但是,确实应该是const char[N],在C++中它也是如此,C++对于const正确性比C更加严格。 - Steve Jessop

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() 函数释放内存。


你的意思是,在我完成s后,应该调用free函数,对吗? - erikbstack

1

另一种不同的方法/答案:我认为错误在于您没有创建指针指向的变量,因此出现了段错误。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接