2012-01-03 75 views
4

如果定义类似下面,为什么我不能写字符串字符,而我*可以*写入字符串对象?

char *s1 = "Hello"; 

为什么我不能做类似下面,

*s1 = 'w'; // gives segmentation fault ...why??? 

如果我这样做下面,

string s1 = "hello"; 

我可以做下面的事情,

*s1 = 'w'; 
+0

[为什么这个C代码导致分段错误?](http://stackoverflow.com/questions/1614723/why-is-this-c-code-causing-a-segmentation-fault) – 2012-01-03 21:38:27

+1

也是http:// stackoverflow。com/questions/943191 – 2012-01-03 21:41:53

+0

不是重复的,因为这些问题只是询问第一部分,不要求与C++字符串大小写区别。 – Mark 2012-01-04 14:58:56

回答

10

因为"Hello"创建了一个const char []。这衰减到const char*而不是char*。在C++中,字符串是只读的。你已经创建了一个指向这样的文字的指针并且正在尝试写入它。

但是当你做

string s1 = "hello"; 

您复制为const char * “你好” 到s1。区别在于第一个例子s1指向只读“hello”,在第二个示例中只读“hello”是复制到非const s1,允许您访问复制的字符串中的元素做你想要的东西。

如果你想*您需要为CHAR数据分配空间和复制招呼进去

char hello[] = "hello"; // creates a char array big enough to hold "hello" 
hello[0] = 'w';   // writes to the 0th char in the array 
+2

'char hello [] =“hello”;'也行。 – 2012-01-03 21:24:26

+0

@Fred,谢谢,更新 – 2012-01-03 21:38:26

+2

只是为了正确:“hello”的类型不是char const *(或者const char *,如果你坚持的话),但是char const [6]在char const的第一次机会时衰减* (或者,接受被分配给char *)。 – 2012-01-03 21:44:34

1

因为Hello驻留在只读存储器中。您的签名实际上应该是

const char* s1 = "Hello"; 

如果你想那么一个可变的缓冲声明s1char[]std::string过载operator [],所以你可以索引它,即s1[index] = 'w'

2

字符串文字通常分配在只读数据段中。

+1

确实如此,但将对话限制在C++定义的抽象机器的范围内会更有帮助。它已经不再使用它来确保字符串文字被视为常量数据;没有必要谈论使其成为有用/安全选择的物理现实,特别是因为这些现实可以在世界范围内和全世界范围内广泛使用的物理实现方面以事实准确度变化。 – 2015-01-18 13:07:17

0

时间混淆的问题做同样的用字符:

char s0[] = "Hello"; 
s0[0] = 'w'; 

这完全是有效!当然,这并不回答原来的问题,所以我们在这里:字符串文字是在只读存储器中创建的。也就是说,它们的类型是char const[n],其中n是字符串的大小(包括终止空字符,即n == 6,对于字符串字面值"Hello"。但是,为什么这个类型可以用来初始化char const*?答案很简单向后兼容性,分别与[旧] C代码兼容性:到const时,它已经成为语言,很多地方已经初始化了char*带有字符串文字,但任何体面的编译器都应该警告这种滥用,然而,

相关问题