数组和指针的区别

4

昨天我在自己编写的 "strcpy" 函数中遇到了一点麻烦。不过现在它可以工作了,但是我还有些疑惑!

char* a = "Hello, World!"; //Works
char b[] = "Hello, World!"; //Works also

strcpy(a, "Hello!"); //Segmentation fault
strcpy(b, "Haha!!"); //Works..

这两者有何区别?为什么字符指针会导致“段错误”?

为什么下面的代码可以正常工作?:

char* a = "Haha"; //works
a = "LOL"; //works..

阅读C语言FAQ的这一部分:http://c-faq.com/aryptr/aryptr2.html - Claudio
我删除了C++标签,因为这是关于C子集的(即使在那里,你也不会自己实现 strcpy)。 - Benjamin Bannier
2个回答

13
char* a = "Hello, World!";

给您一个指向字符串常量的指针。字符串常量可能存在于只读内存中,因此其内容无法更改。

char* a = "Haha"; //works
a = "LOL"; //works..

修改指针a以指向另一个字符串字面量。它不会尝试修改任何一个字符串字面量的内容,因此是安全/正确的。

char b[] = "Hello, World!"

在堆栈上声明一个数组,并使用字符串字面值的内容对其进行初始化。堆栈内存是可写的,因此更改此内存的内容是完全安全的。


所以我不能修改字符指针中的任何一个字符,对吗? - Normal People Scare Me
2
@NormalPeopleScareMe 没错。它指向一个字符串常量 - user1019830
4
嗯,这是未定义的行为,所以它可能有效,也可能无效。我的建议是始终假设它无效。 - Imre Kerr
1
@NormalPeopleScareMe 这取决于它指向什么。你无法修改指向字符串字面值的指针内容,但你可以修改指向堆栈或堆分配的字符串的指针内容。 - simonc
1
谢谢大家。Simonc,你真的帮了我很多! - Normal People Scare Me
1
使用-Wwrite-strings编译将告诉gcc记住常量字符串字面值的方式:它会在此代码上发出警告。 - Medinoc

1
在您的第一个示例中,由于您试图写入由a指向的只读内存,因此会出现分段错误。如果要使用指针,则应在堆上分配内存,在使用后使用delete删除它。 而b是一个用“Hello, World!”初始化的字符数组。
在第二个示例中,您正在使指针指向不同的字符串字面量,这应该是可以的。

我觉得这个答案非常有帮助。我不知道字符串字面量位于只读内存中。此外,我找到了一个教程,介绍如何使用char指针与strcpy结合使用,因为在这里它导致了分段错误,并且他们正在分配内存,我无法追踪为什么他们这样做。谢谢。 - Normal People Scare Me

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