0

可能重复:
为什么简单的 C 代码会收到分段错误?

为什么代码片段 2 的行为不像片段 1?

//Code snippet 1
char pstr[] = "helloworld";
char *p = pstr; 
p[2] = 'd';

//Code snippet 2
char *p = "helloworld";
p[2] = 'd'; //error: access violation

PS 原谅我的无知。

4

4 回答 4

3

第一个片段创建一个 char 数组并将其内容初始化为“helloworld”。然后你改变它的第三个元素。

第二个简单地创建一个指向 char 的指针,该指针指向一个字符串字面量。然后您尝试更改该文字的第三个字符。字符串文字在许多现代编译器生成的代码中是不可写的。

编辑:

GCC 曾经有一个-fwritable-strings选项可以使字符串文字可写,因为周围存在依赖于这种行为的遗留代码。该选项在GCC 4.0 发行系列中被删除。

于 2010-12-24T00:42:37.387 回答
2

"helloworld"是一个数组const char。类型系统中有一个漏洞,允许您使用 a 指向它char*,因为存在很多使用 achar *指向只读数据的代码,这是安全的。

但是规则适用,即使你创建了一个非常量指针const_cast,你也不能真正写入数据。const

于 2010-12-24T00:44:29.977 回答
0

如果您能告诉我们他们的行为方式有何不同,那将会有所帮助。

但作为一个猜测,我认为你的问题是第二种形式有 'p' 指向只读内存中的字符串。尝试通过指针“p”写入将导致程序失败。

我可以告诉你 Gnu c++ 编译器会警告你。

于 2010-12-24T00:41:21.940 回答
0

我猜当你说“行为不像”时,你的意思是一个抛出非法访问异常(或类似的东西),而另一个给出编译时警告或错误?

答案是,在第一种情况下,您正在创建一个指向您自己的内存的指针,并将 c9ontents 复制到其中。那时编译器忘记了它曾经是指向静态内存的指针。然而,运行时系统不会忘记。

在另一种情况下,编译器“知道” p 是指向静态内存的指针,因此有机会说“哇,伙计,不能那样做”。

但这只是一个猜测,不知道它有什么不同。它也将依赖于编译器和实现。

于 2010-12-24T00:42:49.397 回答