2013-04-10 66 views
2

在C++中,为什么编译器不允许修改以下字符指针如下访问字符指针

#include <iostream> 

int main() 
{ 
char* cp = "overflow"; 
cp[1]='p'; 
return 0; 
} 

输出:在运行时崩溃。

但字符数组允许,

#include <iostream> 

int main() 
{ 
char cps[] = "overflow"; 
cp[1]='p'; // this compiles fine and output is operflow 
return 0; 
} 

只是想知道什么是在运行时发生的事情,为何导致崩溃。谢谢。

+1

'char cps =“overflow”;'是错的,你的意思是'char cps [] =“overflow”;'? – unwind 2013-04-10 11:35:28

+0

@unwind对不起,它失踪了。更正.. – 2013-04-10 11:39:03

回答

9

字符串文字是char const[]类型的左值,其中const是重要部分。试图修改类型为const的对象是未定义的行为

每个段落的C++ 11标准2.14.5/8:

普通字符串和UTF-8字符串文字也称为窄字符串文字。 窄 字符串文字具有类型,其中Ñ是字符串的尺寸如下面所定义,且具有 静态存储持续时间(3.7)“的Ñconst char阵列”。

在第二种情况下(假设你的意思char cps[] = "overflow";,用方括号),要初始化字符串字面的非const副本。修改该副本即可。

还要注意,从一个字符串非-constchar *转换已被弃用在C++ 03和非法在C++ 11。这一点,在另一方面,是合法的:

char const* cp = "overflow"; 
// ^^^^^ 
+0

在大多数编译器上,至少应该至少有一个警告,即使是在C++ 11之前? – drquicksilver 2013-04-10 11:39:44

+0

@drquicksilver:在GCC上有提供足够的警告级别。 – ereOn 2013-04-10 11:40:19

+0

@ Andy,为什么它被视为char const [],它背后的任何有效理由? – 2013-04-10 11:42:17

2

此:char* str="";,是一个字符串文字,并且可以存储在只读内存部分,因此可能会崩溃。使用const char* const str="string";(包括指针和数据不变或至少该数据应该是恒定的:const char* str="string";char const* str="string";

如果试图改变一个字符串的内容文本是未定义的行为和分割故障导致的碰撞可能发生。

0

当您设置char* cp = "overflow";时,您正在创建一个只读的内存块,其中包含"overflow"(后跟NULL结束字节),因此您不能在此处写入。试图改变c[x]需要写在那里。

至于你的第二块代码 - 缺少某些东西,以至于部分问题还不清楚。

0

因为指向字符的指针不是arraylow-level const。你可以做

char cp[] = {'o', 'v', 'e', 'r', 'f', 'l', 'o', 'w', '\0'}; 

char *pcp = cp; 

*++pcp = 'p'; 

然而,"overflow"是字符常量序列是不可修改的,因此,你只能执行指针算术和反引用指针的值。

char *cp = "overflow"; 

std::cout << *++cp std::endl;