2013-04-04 182 views
0

时,我有些纳闷,为什么下面炸毁:访问冲突覆盖C字符串

char* c = "Hello World!"; 
*c = 'h'; 

当我分配在它的工作堆的字符串。所以我只是好奇我的初始版本有什么问题。

+0

在现代C++编译器中,这甚至不会编译,或者至少会发出严重警告。 – 2013-04-04 14:25:55

+0

@KonradRudolph你的意思是这个'char * c =“ccxcv”';像char * const c一样行事;'? – 2013-04-04 14:27:22

+0

@Stephane否,作为'char const *',“警告:从字符串文字转换为'char *'已弃用”。 – 2013-04-04 14:27:45

回答

6
char* c = "Hello World!";

是一个指向文字串,其典型地存储在一个只读存储器段。试图修改它是未定义的行为。指针字符串文字如这应该更适当地被定义为

const char *c = "Hello World!"; 

const常被省略(在C,至少)。

+0

@Eric:好点 - 我现在编辑了答案,使它更精确一些。 – 2013-04-04 14:36:32

3
char* c = "Hello World!"; 

这里c是指向一个字符串的指针,所以你不能修改它

你可以用这个来代替

char c[] = "Hello World!"; 
*c = 'h', 

c这里是char类型的数组,并包含字符串"Hello World!"的字符,所以你可以修改它。

2

修改字符串文字是undefined behaviour。主要原因是编译器允许将"Hello World!"放置在只读存储器中。

在另一方面,下面是细:

char c[] = "Hello World!"; 
*c = 'h'; 
+0

向提问者解释他们是如何试图修改字符串文字而不是仅仅声明它是未定义的行为可能是有用的。 – 2013-04-04 14:31:24

3

您将c指向字符串文字,很可能存储在只读内存段中,您无法更改它。即使你可以物理改变,如按照C时的参数:如果程序试图修改[字符串常量]

6.4.5(字符串)中

,该行为是不确定的。

如果您在堆(或堆栈)上分配内存,然后将该字符串复制到该位置,则可以根据需要更改它。

-1

字符串像char * c = "Hello";是字符串常量和存储在只读数据段,所以你不能对其进行修改[但一些编译器也允许]

堆中分配的字符串不是只读段,并因此免费被修改。

+0

我没有投票,但你的回答是错误的。因为'char * p;'指针可能指向一个char数组'char arr [30];'更新uor答案,否则可能会导致更多的downvoted – MOHAMED 2013-04-04 14:40:22

+0

谢谢@Mohamed。我希望那些downvote的人也会添加这个原因 – 2013-04-04 14:42:37

+0

这是我第一次知道有一些编译器允许,请你提供一些参考文献 – MOHAMED 2013-04-04 15:23:33